24 #include "llvm/Support/Path.h"
25 #include "llvm/Support/Timer.h"
26 #include "llvm/Support/raw_ostream.h"
27 using namespace clang;
38 ASTPrinter(raw_ostream *Out =
nullptr,
bool Dump =
false,
39 StringRef FilterString =
"",
bool DumpLookups =
false)
40 : Out(Out ? *Out : llvm::outs()), Dump(Dump),
41 FilterString(FilterString), DumpLookups(DumpLookups) {}
46 if (FilterString.empty())
52 bool shouldWalkTypesOfTypeLocs()
const {
return false; }
54 bool TraverseDecl(
Decl *D) {
55 if (D && filterMatches(D)) {
56 bool ShowColors = Out.has_colors();
58 Out.changeColor(raw_ostream::BLUE);
59 Out << ((Dump || DumpLookups) ?
"Dumping " :
"Printing ") << getName(D)
68 return base::TraverseDecl(D);
72 std::string getName(
Decl *D) {
73 if (isa<NamedDecl>(D))
74 return cast<NamedDecl>(D)->getQualifiedNameAsString();
77 bool filterMatches(
Decl *D) {
78 return getName(D).find(FilterString) != std::string::npos;
83 if (DC == DC->getPrimaryContext())
84 DC->dumpLookups(Out, Dump);
86 Out <<
"Lookup map is in primary DeclContext "
87 << DC->getPrimaryContext() <<
"\n";
89 Out <<
"Not a DeclContext\n";
93 D->
print(Out, 0,
true);
98 std::string FilterString;
105 ASTDeclNodeLister(raw_ostream *Out =
nullptr)
106 : Out(Out ? *Out : llvm::outs()) {}
112 bool shouldWalkTypesOfTypeLocs()
const {
return false; }
126 StringRef FilterString) {
127 return llvm::make_unique<ASTPrinter>(Out,
false, FilterString);
133 assert((DumpDecls || DumpLookups) &&
"nothing to dump");
134 return llvm::make_unique<ASTPrinter>(
nullptr, DumpDecls, FilterString,
139 return llvm::make_unique<ASTDeclNodeLister>(
nullptr);
149 void Initialize(
ASTContext &Context)
override {
155 HandleTopLevelSingleDecl(*I);
159 void HandleTopLevelSingleDecl(
Decl *D);
163 void ASTViewer::HandleTopLevelSingleDecl(
Decl *D) {
164 if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
165 D->
print(llvm::errs());
168 llvm::errs() <<
'\n';
170 llvm::errs() <<
'\n';
176 return llvm::make_unique<ASTViewer>();
187 DeclContextPrinter() : Out(llvm::errs()) {}
189 void HandleTranslationUnit(
ASTContext &
C)
override {
198 unsigned Indentation) {
201 case Decl::TranslationUnit:
202 Out <<
"[translation unit] " << DC;
204 case Decl::Namespace: {
205 Out <<
"[namespace] ";
211 const EnumDecl* ED = cast<EnumDecl>(DC);
228 case Decl::CXXRecord: {
234 Out << *RD <<
' ' << DC;
237 case Decl::ObjCMethod:
238 Out <<
"[objc method]";
240 case Decl::ObjCInterface:
241 Out <<
"[objc interface]";
243 case Decl::ObjCCategory:
244 Out <<
"[objc category]";
246 case Decl::ObjCProtocol:
247 Out <<
"[objc protocol]";
249 case Decl::ObjCImplementation:
250 Out <<
"[objc implementation]";
252 case Decl::ObjCCategoryImpl:
253 Out <<
"[objc categoryimpl]";
255 case Decl::LinkageSpec:
256 Out <<
"[linkage spec]";
261 case Decl::Function: {
264 Out <<
"[function] ";
266 Out <<
"<function> ";
270 bool PrintComma =
false;
271 for (
auto I : FD->params()) {
281 case Decl::CXXMethod: {
284 Out <<
"[c++ method] ";
286 Out <<
"(c++ method) ";
288 Out <<
"<c++ method> ";
292 bool PrintComma =
false;
294 E = D->param_end(); I != E; ++I) {
305 const DeclContext* LexicalDC = D->getLexicalDeclContext();
306 if (SemaDC != LexicalDC)
307 Out <<
" [[" << SemaDC <<
"]]";
311 case Decl::CXXConstructor: {
314 Out <<
"[c++ ctor] ";
316 Out <<
"(c++ ctor) ";
318 Out <<
"<c++ ctor> ";
322 bool PrintComma =
false;
324 E = D->param_end(); I != E; ++I) {
335 const DeclContext* LexicalDC = D->getLexicalDeclContext();
336 if (SemaDC != LexicalDC)
337 Out <<
" [[" << SemaDC <<
"]]";
340 case Decl::CXXDestructor: {
343 Out <<
"[c++ dtor] ";
345 Out <<
"(c++ dtor) ";
347 Out <<
"<c++ dtor> ";
351 const DeclContext* LexicalDC = D->getLexicalDeclContext();
352 if (SemaDC != LexicalDC)
353 Out <<
" [[" << SemaDC <<
"]]";
356 case Decl::CXXConversion: {
359 Out <<
"[c++ conversion] ";
361 Out <<
"(c++ conversion) ";
363 Out <<
"<c++ conversion> ";
367 const DeclContext* LexicalDC = D->getLexicalDeclContext();
368 if (SemaDC != LexicalDC)
369 Out <<
" [[" << SemaDC <<
"]]";
374 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
380 for (
auto *I : DC->decls()) {
381 for (
unsigned i = 0; i < Indentation; ++i)
386 case Decl::Namespace:
389 case Decl::CXXRecord:
390 case Decl::ObjCMethod:
391 case Decl::ObjCInterface:
392 case Decl::ObjCCategory:
393 case Decl::ObjCProtocol:
394 case Decl::ObjCImplementation:
395 case Decl::ObjCCategoryImpl:
396 case Decl::LinkageSpec:
399 case Decl::CXXMethod:
400 case Decl::CXXConstructor:
401 case Decl::CXXDestructor:
402 case Decl::CXXConversion:
408 case Decl::IndirectField: {
410 Out <<
"<IndirectField> " << *IFD <<
'\n';
415 Out <<
"<Label> " << *LD <<
'\n';
420 Out <<
"<field> " << *FD <<
'\n';
424 case Decl::TypeAlias: {
426 Out <<
"<typedef> " << *TD <<
'\n';
429 case Decl::EnumConstant: {
431 Out <<
"<enum constant> " << *ECD <<
'\n';
435 VarDecl* VD = cast<VarDecl>(I);
436 Out <<
"<var> " << *VD <<
'\n';
439 case Decl::ImplicitParam: {
441 Out <<
"<implicit parameter> " << *IPD <<
'\n';
444 case Decl::ParmVar: {
446 Out <<
"<parameter> " << *PVD <<
'\n';
449 case Decl::ObjCProperty: {
451 Out <<
"<objc property> " << *OPD <<
'\n';
454 case Decl::FunctionTemplate: {
456 Out <<
"<function template> " << *FTD <<
'\n';
459 case Decl::FileScopeAsm: {
460 Out <<
"<file-scope asm>\n";
463 case Decl::UsingDirective: {
464 Out <<
"<using directive>\n";
467 case Decl::NamespaceAlias: {
469 Out <<
"<namespace alias> " << *NAD <<
'\n';
472 case Decl::ClassTemplate: {
474 Out <<
"<class template> " << *CTD <<
'\n';
477 case Decl::OMPThreadPrivate: {
478 Out <<
"<omp threadprivate> " <<
'"' << I <<
"\"\n";
482 Out <<
"DeclKind: " << DK <<
'"' << I <<
"\"\n";
483 llvm_unreachable(
"decl unhandled");
488 return llvm::make_unique<DeclContextPrinter>();
Defines the clang::ASTContext interface.
ParmVarDecl *const * param_const_iterator
Defines the clang::FileManager interface and associated types.
bool isOutOfLine() const override
Determine whether this is or was instantiated from an out-of-line definition of a member function...
Defines the SourceManager interface.
NamespaceDecl - Represent a C++ namespace.
Represents a C++ constructor within a class.
ParmVarDecl - Represents a parameter to a function.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
bool isCompleteDefinition() const
Print DeclContext and their Decls.
A class that does preorder depth-first traversal on the entire Clang AST and visits each node...
Represents a C++ destructor within a class.
TranslationUnitDecl * getTranslationUnitDecl() const
virtual void HandleTranslationUnit(ASTContext &Ctx)
Represents a C++ conversion function within a class.
bool doesThisDeclarationHaveABody() const
Represents a static or instance method of a struct/union/class.
virtual Stmt * getBody() const
Represents one property declaration in an Objective-C interface.
void printQualifiedName(raw_ostream &OS) const
Base class for declarations which introduce a typedef-name.
std::unique_ptr< ASTConsumer > CreateASTPrinter(raw_ostream *OS, StringRef FilterString)
Defines the Diagnostic-related interfaces.
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
std::unique_ptr< ASTConsumer > CreateDeclContextPrinter()
Decl::Kind getDeclKind() const
std::unique_ptr< ASTConsumer > CreateASTViewer()
std::unique_ptr< ASTConsumer > CreateASTDeclNodeLister()
Represents a C++ struct/union/class.
Declaration of a class template.
Kind
Lists the kind of concrete classes of Decl.
TranslationUnitDecl - The top declaration context.
std::unique_ptr< ASTConsumer > CreateASTDumper(StringRef FilterString, bool DumpDecls, bool DumpLookups)
Represents a C++ namespace alias.
Declaration of a template function.