blob: 043b2541b8f871cf22f197ada60d24e96456f9b1 [file] [log] [blame]
Chris Lattnerd1cdee72007-10-07 06:04:32 +00001//===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//
Bill Wendlingaec64c32007-06-23 00:39:57 +00002//
Chandler Carruth2946cd72019-01-19 08:50:56 +00003// 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
Bill Wendlingaec64c32007-06-23 00:39:57 +00006//
7//===----------------------------------------------------------------------===//
8//
Chris Lattnerd1cdee72007-10-07 06:04:32 +00009// AST Consumer Implementations.
Bill Wendlingaec64c32007-06-23 00:39:57 +000010//
11//===----------------------------------------------------------------------===//
12
Eli Friedman9f30fc32009-05-18 22:50:54 +000013#include "clang/Frontend/ASTConsumers.h"
Bill Wendlingaec64c32007-06-23 00:39:57 +000014#include "clang/AST/AST.h"
Chris Lattner09c39db2007-09-15 23:02:28 +000015#include "clang/AST/ASTConsumer.h"
Chris Lattnera5adead2009-03-28 04:27:18 +000016#include "clang/AST/ASTContext.h"
Douglas Gregor7de59662009-05-29 20:38:28 +000017#include "clang/AST/PrettyPrinter.h"
Alexander Kornienko3db68ee2012-07-26 16:01:23 +000018#include "clang/AST/RecordLayout.h"
19#include "clang/AST/RecursiveASTVisitor.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000020#include "clang/Basic/Diagnostic.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000021#include "clang/Basic/SourceManager.h"
Michael J. Spencer8aaf4992010-11-29 18:12:39 +000022#include "llvm/Support/Path.h"
Alexander Kornienko3db68ee2012-07-26 16:01:23 +000023#include "llvm/Support/Timer.h"
Chandler Carruth3a022472012-12-04 09:13:33 +000024#include "llvm/Support/raw_ostream.h"
Chris Lattnercbe4f772007-08-08 22:51:59 +000025using namespace clang;
Bill Wendlingaec64c32007-06-23 00:39:57 +000026
Ted Kremenek7c81bdd2007-11-27 21:46:50 +000027//===----------------------------------------------------------------------===//
Douglas Gregor278f52e2009-05-30 00:08:05 +000028/// ASTPrinter - Pretty-printer and dumper of ASTs
Chris Lattnercbe4f772007-08-08 22:51:59 +000029
Ted Kremenek7c81bdd2007-11-27 21:46:50 +000030namespace {
Alexander Kornienko3db68ee2012-07-26 16:01:23 +000031 class ASTPrinter : public ASTConsumer,
32 public RecursiveASTVisitor<ASTPrinter> {
33 typedef RecursiveASTVisitor<ASTPrinter> base;
Mike Stump11289f42009-09-09 15:08:12 +000034
Ted Kremenek7c81bdd2007-11-27 21:46:50 +000035 public:
Richard Smith3a36ac12017-03-09 22:00:01 +000036 enum Kind { DumpFull, Dump, Print, None };
Aaron Ballman2ce598a2019-05-13 21:39:55 +000037 ASTPrinter(std::unique_ptr<raw_ostream> Out, Kind K,
38 ASTDumpOutputFormat Format, StringRef FilterString,
Richard Smith3a36ac12017-03-09 22:00:01 +000039 bool DumpLookups = false)
40 : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)),
Aaron Ballman2ce598a2019-05-13 21:39:55 +000041 OutputKind(K), OutputFormat(Format), FilterString(FilterString),
42 DumpLookups(DumpLookups) {}
Mike Stump11289f42009-09-09 15:08:12 +000043
Craig Topperafa7cb32014-03-13 06:07:04 +000044 void HandleTranslationUnit(ASTContext &Context) override {
Alexander Kornienko3db68ee2012-07-26 16:01:23 +000045 TranslationUnitDecl *D = Context.getTranslationUnitDecl();
46
Richard Smith6ea05822013-06-24 01:45:33 +000047 if (FilterString.empty())
48 return print(D);
Alexander Kornienko3db68ee2012-07-26 16:01:23 +000049
50 TraverseDecl(D);
Bill Wendlingaec64c32007-06-23 00:39:57 +000051 }
Alexander Kornienko3db68ee2012-07-26 16:01:23 +000052
53 bool shouldWalkTypesOfTypeLocs() const { return false; }
54
55 bool TraverseDecl(Decl *D) {
Craig Topper49a27902014-05-22 04:46:25 +000056 if (D && filterMatches(D)) {
Dmitri Gribenko32333912012-11-21 10:54:55 +000057 bool ShowColors = Out.has_colors();
58 if (ShowColors)
Dmitri Gribenkof8579502013-01-12 19:30:44 +000059 Out.changeColor(raw_ostream::BLUE);
Richard Smith3a36ac12017-03-09 22:00:01 +000060 Out << (OutputKind != Print ? "Dumping " : "Printing ") << getName(D)
Richard Smith35f986d2014-08-11 22:11:07 +000061 << ":\n";
Dmitri Gribenko32333912012-11-21 10:54:55 +000062 if (ShowColors)
63 Out.resetColor();
Richard Smith6ea05822013-06-24 01:45:33 +000064 print(D);
Alexander Kornienko20186182012-08-17 17:38:39 +000065 Out << "\n";
Alexander Kornienko3db68ee2012-07-26 16:01:23 +000066 // Don't traverse child nodes to avoid output duplication.
67 return true;
68 }
69 return base::TraverseDecl(D);
70 }
71
72 private:
73 std::string getName(Decl *D) {
74 if (isa<NamedDecl>(D))
75 return cast<NamedDecl>(D)->getQualifiedNameAsString();
76 return "";
77 }
78 bool filterMatches(Decl *D) {
79 return getName(D).find(FilterString) != std::string::npos;
80 }
Richard Smith6ea05822013-06-24 01:45:33 +000081 void print(Decl *D) {
82 if (DumpLookups) {
Richard Smith35f986d2014-08-11 22:11:07 +000083 if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
84 if (DC == DC->getPrimaryContext())
Richard Smith3a36ac12017-03-09 22:00:01 +000085 DC->dumpLookups(Out, OutputKind != None, OutputKind == DumpFull);
Richard Smith35f986d2014-08-11 22:11:07 +000086 else
87 Out << "Lookup map is in primary DeclContext "
88 << DC->getPrimaryContext() << "\n";
89 } else
Richard Smith6ea05822013-06-24 01:45:33 +000090 Out << "Not a DeclContext\n";
Joel E. Denny7bcc2102018-05-14 18:41:44 +000091 } else if (OutputKind == Print) {
92 PrintingPolicy Policy(D->getASTContext().getLangOpts());
93 D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
94 } else if (OutputKind != None)
Aaron Ballman2ce598a2019-05-13 21:39:55 +000095 D->dump(Out, OutputKind == DumpFull, OutputFormat);
Richard Smith6ea05822013-06-24 01:45:33 +000096 }
Alexander Kornienko3db68ee2012-07-26 16:01:23 +000097
98 raw_ostream &Out;
Peter Collingbourne03f89072016-07-15 00:55:40 +000099 std::unique_ptr<raw_ostream> OwnedOut;
Richard Smith3a36ac12017-03-09 22:00:01 +0000100
101 /// How to output individual declarations.
102 Kind OutputKind;
103
Aaron Ballman2ce598a2019-05-13 21:39:55 +0000104 /// What format should the output take?
105 ASTDumpOutputFormat OutputFormat;
106
Richard Smith3a36ac12017-03-09 22:00:01 +0000107 /// Which declarations or DeclContexts to display.
Alexander Kornienko3db68ee2012-07-26 16:01:23 +0000108 std::string FilterString;
Richard Smith3a36ac12017-03-09 22:00:01 +0000109
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.
Richard Smith6ea05822013-06-24 01:45:33 +0000113 bool DumpLookups;
Chris Lattner09c39db2007-09-15 23:02:28 +0000114 };
Alexander Kornienko4de03592012-07-31 09:37:40 +0000115
116 class ASTDeclNodeLister : public ASTConsumer,
117 public RecursiveASTVisitor<ASTDeclNodeLister> {
Alexander Kornienko4de03592012-07-31 09:37:40 +0000118 public:
Craig Topper49a27902014-05-22 04:46:25 +0000119 ASTDeclNodeLister(raw_ostream *Out = nullptr)
Alexander Kornienko4de03592012-07-31 09:37:40 +0000120 : Out(Out ? *Out : llvm::outs()) {}
121
Craig Topperafa7cb32014-03-13 06:07:04 +0000122 void HandleTranslationUnit(ASTContext &Context) override {
Alexander Kornienko4de03592012-07-31 09:37:40 +0000123 TraverseDecl(Context.getTranslationUnitDecl());
124 }
125
126 bool shouldWalkTypesOfTypeLocs() const { return false; }
127
Craig Topper45670532014-03-13 07:14:47 +0000128 bool VisitNamedDecl(NamedDecl *D) {
Benjamin Kramer24ebf7c2013-02-23 13:53:57 +0000129 D->printQualifiedName(Out);
130 Out << '\n';
Alexander Kornienko4de03592012-07-31 09:37:40 +0000131 return true;
132 }
133
134 private:
135 raw_ostream &Out;
136 };
Chris Lattnerc0c3dff2009-03-28 05:44:17 +0000137} // end anonymous namespace
Chris Lattnercbe4f772007-08-08 22:51:59 +0000138
Peter Collingbourne03f89072016-07-15 00:55:40 +0000139std::unique_ptr<ASTConsumer>
140clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out,
141 StringRef FilterString) {
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +0000142 return std::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,
Aaron Ballman2ce598a2019-05-13 21:39:55 +0000143 ADOF_Default, FilterString);
Ted Kremenek59337682007-11-28 21:32:21 +0000144}
Ted Kremenek7c81bdd2007-11-27 21:46:50 +0000145
Alexander Kornienkod10d7902018-04-06 13:01:12 +0000146std::unique_ptr<ASTConsumer>
Aaron Ballman2ce598a2019-05-13 21:39:55 +0000147clang::CreateASTDumper(std::unique_ptr<raw_ostream> Out, StringRef FilterString,
148 bool DumpDecls, bool Deserialize, bool DumpLookups,
149 ASTDumpOutputFormat Format) {
Aaron Ballman08d3b392017-06-15 00:00:08 +0000150 assert((DumpDecls || Deserialize || DumpLookups) && "nothing to dump");
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +0000151 return std::make_unique<ASTPrinter>(std::move(Out),
Richard Smith3a36ac12017-03-09 22:00:01 +0000152 Deserialize ? ASTPrinter::DumpFull :
153 DumpDecls ? ASTPrinter::Dump :
Aaron Ballman2ce598a2019-05-13 21:39:55 +0000154 ASTPrinter::None, Format,
Richard Smith3a36ac12017-03-09 22:00:01 +0000155 FilterString, DumpLookups);
Douglas Gregor32887f02009-04-26 02:02:08 +0000156}
Chris Lattner09c39db2007-09-15 23:02:28 +0000157
David Blaikie6beb6aa2014-08-10 19:56:51 +0000158std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +0000159 return std::make_unique<ASTDeclNodeLister>(nullptr);
Alexander Kornienko4de03592012-07-31 09:37:40 +0000160}
161
Ted Kremenek7c81bdd2007-11-27 21:46:50 +0000162//===----------------------------------------------------------------------===//
163/// ASTViewer - AST Visualization
164
Ted Kremenek66d130a2007-09-19 21:29:43 +0000165namespace {
166 class ASTViewer : public ASTConsumer {
Douglas Gregor278f52e2009-05-30 00:08:05 +0000167 ASTContext *Context;
Ted Kremenek66d130a2007-09-19 21:29:43 +0000168 public:
Craig Topperafa7cb32014-03-13 06:07:04 +0000169 void Initialize(ASTContext &Context) override {
Douglas Gregor278f52e2009-05-30 00:08:05 +0000170 this->Context = &Context;
Ted Kremenek66d130a2007-09-19 21:29:43 +0000171 }
Chris Lattner5bbb3c82009-03-29 16:50:03 +0000172
Craig Topperafa7cb32014-03-13 06:07:04 +0000173 bool HandleTopLevelDecl(DeclGroupRef D) override {
Chris Lattner5bbb3c82009-03-29 16:50:03 +0000174 for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
175 HandleTopLevelSingleDecl(*I);
Argyrios Kyrtzidis841dd882011-11-18 00:26:59 +0000176 return true;
Chris Lattner5bbb3c82009-03-29 16:50:03 +0000177 }
Mike Stump11289f42009-09-09 15:08:12 +0000178
Chris Lattner5bbb3c82009-03-29 16:50:03 +0000179 void HandleTopLevelSingleDecl(Decl *D);
Ted Kremenek66d130a2007-09-19 21:29:43 +0000180 };
Alexander Kornienkoab9db512015-06-22 23:07:51 +0000181}
Ted Kremenek66d130a2007-09-19 21:29:43 +0000182
Chris Lattner5bbb3c82009-03-29 16:50:03 +0000183void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
Argyrios Kyrtzidis46f556d2010-07-07 11:31:23 +0000184 if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
185 D->print(llvm::errs());
Fangrui Song6907ce22018-07-30 19:24:48 +0000186
Argyrios Kyrtzidis46f556d2010-07-07 11:31:23 +0000187 if (Stmt *Body = D->getBody()) {
Benjamin Kramer89b422c2009-08-23 12:08:50 +0000188 llvm::errs() << '\n';
Douglas Gregore2350a32009-09-12 00:08:48 +0000189 Body->viewAST();
Benjamin Kramer89b422c2009-08-23 12:08:50 +0000190 llvm::errs() << '\n';
Chris Lattnerc0c3dff2009-03-28 05:44:17 +0000191 }
Chris Lattnerc0c3dff2009-03-28 05:44:17 +0000192 }
193}
194
David Blaikie6beb6aa2014-08-10 19:56:51 +0000195std::unique_ptr<ASTConsumer> clang::CreateASTViewer() {
Jonas Devlieghere2b3d49b2019-08-14 23:04:18 +0000196 return std::make_unique<ASTViewer>();
David Blaikie6beb6aa2014-08-10 19:56:51 +0000197}