blob: 28834a2de8a2649d881d35e307cc7c31625c9b67 [file] [log] [blame]
Chris Lattnerd1cdee72007-10-07 06:04:32 +00001//===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//
Bill Wendlingaec64c32007-06-23 00:39:57 +00002//
3// The LLVM Compiler Infrastructure
4//
Chris Lattner5b12ab82007-12-29 19:59:25 +00005// This file is distributed under the University of Illinois Open Source
6// License. See LICENSE.TXT for details.
Bill Wendlingaec64c32007-06-23 00:39:57 +00007//
8//===----------------------------------------------------------------------===//
9//
Chris Lattnerd1cdee72007-10-07 06:04:32 +000010// AST Consumer Implementations.
Bill Wendlingaec64c32007-06-23 00:39:57 +000011//
12//===----------------------------------------------------------------------===//
13
Eli Friedman9f30fc32009-05-18 22:50:54 +000014#include "clang/Frontend/ASTConsumers.h"
Bill Wendlingaec64c32007-06-23 00:39:57 +000015#include "clang/AST/AST.h"
Chris Lattner09c39db2007-09-15 23:02:28 +000016#include "clang/AST/ASTConsumer.h"
Chris Lattnera5adead2009-03-28 04:27:18 +000017#include "clang/AST/ASTContext.h"
Douglas Gregor7de59662009-05-29 20:38:28 +000018#include "clang/AST/PrettyPrinter.h"
Alexander Kornienko3db68ee2012-07-26 16:01:23 +000019#include "clang/AST/RecordLayout.h"
20#include "clang/AST/RecursiveASTVisitor.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000021#include "clang/Basic/Diagnostic.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000022#include "clang/Basic/SourceManager.h"
Michael J. Spencer8aaf4992010-11-29 18:12:39 +000023#include "llvm/Support/Path.h"
Alexander Kornienko3db68ee2012-07-26 16:01:23 +000024#include "llvm/Support/Timer.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000025#include "llvm/Support/raw_ostream.h"
Chris Lattnercbe4f772007-08-08 22:51:59 +000026using namespace clang;
Bill Wendlingaec64c32007-06-23 00:39:57 +000027
Ted Kremenek7c81bdd2007-11-27 21:46:50 +000028//===----------------------------------------------------------------------===//
Douglas Gregor278f52e2009-05-30 00:08:05 +000029/// ASTPrinter - Pretty-printer and dumper of ASTs
Chris Lattnercbe4f772007-08-08 22:51:59 +000030
Ted Kremenek7c81bdd2007-11-27 21:46:50 +000031namespace {
Alexander Kornienko3db68ee2012-07-26 16:01:23 +000032 class ASTPrinter : public ASTConsumer,
33 public RecursiveASTVisitor<ASTPrinter> {
34 typedef RecursiveASTVisitor<ASTPrinter> base;
Mike Stump11289f42009-09-09 15:08:12 +000035
Ted Kremenek7c81bdd2007-11-27 21:46:50 +000036 public:
Richard Smith3a36ac12017-03-09 22:00:01 +000037 enum Kind { DumpFull, Dump, Print, None };
38 ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K, StringRef FilterString,
39 bool DumpLookups = false)
40 : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)),
41 OutputKind(K), FilterString(FilterString), DumpLookups(DumpLookups) {}
Mike Stump11289f42009-09-09 15:08:12 +000042
Craig Topperafa7cb32014-03-13 06:07:04 +000043 void HandleTranslationUnit(ASTContext &Context) override {
Alexander Kornienko3db68ee2012-07-26 16:01:23 +000044 TranslationUnitDecl *D = Context.getTranslationUnitDecl();
45
Richard Smith6ea05822013-06-24 01:45:33 +000046 if (FilterString.empty())
47 return print(D);
Alexander Kornienko3db68ee2012-07-26 16:01:23 +000048
49 TraverseDecl(D);
Bill Wendlingaec64c32007-06-23 00:39:57 +000050 }
Alexander Kornienko3db68ee2012-07-26 16:01:23 +000051
52 bool shouldWalkTypesOfTypeLocs() const { return false; }
53
54 bool TraverseDecl(Decl *D) {
Craig Topper49a27902014-05-22 04:46:25 +000055 if (D && filterMatches(D)) {
Dmitri Gribenko32333912012-11-21 10:54:55 +000056 bool ShowColors = Out.has_colors();
57 if (ShowColors)
Dmitri Gribenkof8579502013-01-12 19:30:44 +000058 Out.changeColor(raw_ostream::BLUE);
Richard Smith3a36ac12017-03-09 22:00:01 +000059 Out << (OutputKind != Print ? "Dumping " : "Printing ") << getName(D)
Richard Smith35f986d2014-08-11 22:11:07 +000060 << ":\n";
Dmitri Gribenko32333912012-11-21 10:54:55 +000061 if (ShowColors)
62 Out.resetColor();
Richard Smith6ea05822013-06-24 01:45:33 +000063 print(D);
Alexander Kornienko20186182012-08-17 17:38:39 +000064 Out << "\n";
Alexander Kornienko3db68ee2012-07-26 16:01:23 +000065 // Don't traverse child nodes to avoid output duplication.
66 return true;
67 }
68 return base::TraverseDecl(D);
69 }
70
71 private:
72 std::string getName(Decl *D) {
73 if (isa<NamedDecl>(D))
74 return cast<NamedDecl>(D)->getQualifiedNameAsString();
75 return "";
76 }
77 bool filterMatches(Decl *D) {
78 return getName(D).find(FilterString) != std::string::npos;
79 }
Richard Smith6ea05822013-06-24 01:45:33 +000080 void print(Decl *D) {
81 if (DumpLookups) {
Richard Smith35f986d2014-08-11 22:11:07 +000082 if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
83 if (DC == DC->getPrimaryContext())
Richard Smith3a36ac12017-03-09 22:00:01 +000084 DC->dumpLookups(Out, OutputKind != None, OutputKind == DumpFull);
Richard Smith35f986d2014-08-11 22:11:07 +000085 else
86 Out << "Lookup map is in primary DeclContext "
87 << DC->getPrimaryContext() << "\n";
88 } else
Richard Smith6ea05822013-06-24 01:45:33 +000089 Out << "Not a DeclContext\n";
Joel E. Denny7bcc2102018-05-14 18:41:44 +000090 } else if (OutputKind == Print) {
91 PrintingPolicy Policy(D->getASTContext().getLangOpts());
92 D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
93 } else if (OutputKind != None)
Richard Smith3a36ac12017-03-09 22:00:01 +000094 D->dump(Out, OutputKind == DumpFull);
Richard Smith6ea05822013-06-24 01:45:33 +000095 }
Alexander Kornienko3db68ee2012-07-26 16:01:23 +000096
97 raw_ostream &Out;
Peter Collingbourne03f89072016-07-15 00:55:40 +000098 std::unique_ptr<raw_ostream> OwnedOut;
Richard Smith3a36ac12017-03-09 22:00:01 +000099
100 /// How to output individual declarations.
101 Kind OutputKind;
102
103 /// Which declarations or DeclContexts to display.
Alexander Kornienko3db68ee2012-07-26 16:01:23 +0000104 std::string FilterString;
Richard Smith3a36ac12017-03-09 22:00:01 +0000105
106 /// Whether the primary output is lookup results or declarations. Individual
107 /// results will be output with a format determined by OutputKind. This is
108 /// incompatible with OutputKind == Print.
Richard Smith6ea05822013-06-24 01:45:33 +0000109 bool DumpLookups;
Chris Lattner09c39db2007-09-15 23:02:28 +0000110 };
Alexander Kornienko4de03592012-07-31 09:37:40 +0000111
112 class ASTDeclNodeLister : public ASTConsumer,
113 public RecursiveASTVisitor<ASTDeclNodeLister> {
Alexander Kornienko4de03592012-07-31 09:37:40 +0000114 public:
Craig Topper49a27902014-05-22 04:46:25 +0000115 ASTDeclNodeLister(raw_ostream *Out = nullptr)
Alexander Kornienko4de03592012-07-31 09:37:40 +0000116 : Out(Out ? *Out : llvm::outs()) {}
117
Craig Topperafa7cb32014-03-13 06:07:04 +0000118 void HandleTranslationUnit(ASTContext &Context) override {
Alexander Kornienko4de03592012-07-31 09:37:40 +0000119 TraverseDecl(Context.getTranslationUnitDecl());
120 }
121
122 bool shouldWalkTypesOfTypeLocs() const { return false; }
123
Craig Topper45670532014-03-13 07:14:47 +0000124 bool VisitNamedDecl(NamedDecl *D) {
Benjamin Kramer24ebf7c2013-02-23 13:53:57 +0000125 D->printQualifiedName(Out);
126 Out << '\n';
Alexander Kornienko4de03592012-07-31 09:37:40 +0000127 return true;
128 }
129
130 private:
131 raw_ostream &Out;
132 };
Chris Lattnerc0c3dff2009-03-28 05:44:17 +0000133} // end anonymous namespace
Chris Lattnercbe4f772007-08-08 22:51:59 +0000134
Peter Collingbourne03f89072016-07-15 00:55:40 +0000135std::unique_ptr<ASTConsumer>
136clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out,
137 StringRef FilterString) {
Richard Smith3a36ac12017-03-09 22:00:01 +0000138 return llvm::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,
Peter Collingbourne03f89072016-07-15 00:55:40 +0000139 FilterString);
Ted Kremenek59337682007-11-28 21:32:21 +0000140}
Ted Kremenek7c81bdd2007-11-27 21:46:50 +0000141
Alexander Kornienkod10d7902018-04-06 13:01:12 +0000142std::unique_ptr<ASTConsumer>
143clang::CreateASTDumper(std::unique_ptr<raw_ostream> Out,
144 StringRef FilterString,
145 bool DumpDecls,
146 bool Deserialize,
147 bool DumpLookups) {
Aaron Ballman08d3b392017-06-15 00:00:08 +0000148 assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");
Alexander Kornienkod10d7902018-04-06 13:01:12 +0000149 return llvm::make_unique<ASTPrinter>(std::move(Out),
Richard Smith3a36ac12017-03-09 22:00:01 +0000150 Deserialize ? ASTPrinter::DumpFull :
151 DumpDecls ? ASTPrinter::Dump :
152 ASTPrinter::None,
153 FilterString, DumpLookups);
Douglas Gregor32887f02009-04-26 02:02:08 +0000154}
Chris Lattner09c39db2007-09-15 23:02:28 +0000155
David Blaikie6beb6aa2014-08-10 19:56:51 +0000156std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {
157 return llvm::make_unique<ASTDeclNodeLister>(nullptr);
Alexander Kornienko4de03592012-07-31 09:37:40 +0000158}
159
Ted Kremenek7c81bdd2007-11-27 21:46:50 +0000160//===----------------------------------------------------------------------===//
161/// ASTViewer - AST Visualization
162
Ted Kremenek66d130a2007-09-19 21:29:43 +0000163namespace {
164 class ASTViewer : public ASTConsumer {
Douglas Gregor278f52e2009-05-30 00:08:05 +0000165 ASTContext *Context;
Ted Kremenek66d130a2007-09-19 21:29:43 +0000166 public:
Craig Topperafa7cb32014-03-13 06:07:04 +0000167 void Initialize(ASTContext &Context) override {
Douglas Gregor278f52e2009-05-30 00:08:05 +0000168 this->Context = &Context;
Ted Kremenek66d130a2007-09-19 21:29:43 +0000169 }
Chris Lattner5bbb3c82009-03-29 16:50:03 +0000170
Craig Topperafa7cb32014-03-13 06:07:04 +0000171 bool HandleTopLevelDecl(DeclGroupRef D) override {
Chris Lattner5bbb3c82009-03-29 16:50:03 +0000172 for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
173 HandleTopLevelSingleDecl(*I);
Argyrios Kyrtzidis841dd882011-11-18 00:26:59 +0000174 return true;
Chris Lattner5bbb3c82009-03-29 16:50:03 +0000175 }
Mike Stump11289f42009-09-09 15:08:12 +0000176
Chris Lattner5bbb3c82009-03-29 16:50:03 +0000177 void HandleTopLevelSingleDecl(Decl *D);
Ted Kremenek66d130a2007-09-19 21:29:43 +0000178 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +0000179}
Ted Kremenek66d130a2007-09-19 21:29:43 +0000180
Chris Lattner5bbb3c82009-03-29 16:50:03 +0000181void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
Argyrios Kyrtzidis46f556d2010-07-07 11:31:23 +0000182 if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
183 D->print(llvm::errs());
Fangrui Song6907ce22018-07-30 19:24:48 +0000184
Argyrios Kyrtzidis46f556d2010-07-07 11:31:23 +0000185 if (Stmt *Body = D->getBody()) {
Benjamin Kramer89b422c2009-08-23 12:08:50 +0000186 llvm::errs() << '\n';
Douglas Gregore2350a32009-09-12 00:08:48 +0000187 Body->viewAST();
Benjamin Kramer89b422c2009-08-23 12:08:50 +0000188 llvm::errs() << '\n';
Chris Lattnerc0c3dff2009-03-28 05:44:17 +0000189 }
Chris Lattnerc0c3dff2009-03-28 05:44:17 +0000190 }
191}
192
David Blaikie6beb6aa2014-08-10 19:56:51 +0000193std::unique_ptr<ASTConsumer> clang::CreateASTViewer() {
194 return llvm::make_unique<ASTViewer>();
195}