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(std::unique_ptr<raw_ostream> Out =
nullptr,
bool Dump =
false,
39 StringRef FilterString =
"",
bool DumpLookups =
false)
40 : Out(Out ? *Out : llvm::outs()), OwnedOut(std::move(Out)), 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);
97 std::unique_ptr<raw_ostream> OwnedOut;
99 std::string FilterString;
106 ASTDeclNodeLister(raw_ostream *Out =
nullptr)
107 : Out(Out ? *Out : llvm::outs()) {}
113 bool shouldWalkTypesOfTypeLocs()
const {
return false; }
126 std::unique_ptr<ASTConsumer>
128 StringRef FilterString) {
129 return llvm::make_unique<ASTPrinter>(std::move(Out),
false,
136 assert((DumpDecls || DumpLookups) &&
"nothing to dump");
137 return llvm::make_unique<ASTPrinter>(
nullptr, DumpDecls, FilterString,
142 return llvm::make_unique<ASTDeclNodeLister>(
nullptr);
152 void Initialize(
ASTContext &Context)
override {
158 HandleTopLevelSingleDecl(*
I);
162 void HandleTopLevelSingleDecl(
Decl *D);
166 void ASTViewer::HandleTopLevelSingleDecl(
Decl *D) {
167 if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
168 D->print(llvm::errs());
170 if (
Stmt *Body = D->getBody()) {
171 llvm::errs() <<
'\n';
173 llvm::errs() <<
'\n';
179 return llvm::make_unique<ASTViewer>();
190 DeclContextPrinter() : Out(llvm::errs()) {}
192 void HandleTranslationUnit(
ASTContext &C)
override {
201 unsigned Indentation) {
204 case Decl::TranslationUnit:
205 Out <<
"[translation unit] " << DC;
207 case Decl::Namespace: {
208 Out <<
"[namespace] ";
214 const EnumDecl* ED = cast<EnumDecl>(DC);
231 case Decl::CXXRecord: {
237 Out << *RD <<
' ' << DC;
240 case Decl::ObjCMethod:
241 Out <<
"[objc method]";
243 case Decl::ObjCInterface:
244 Out <<
"[objc interface]";
246 case Decl::ObjCCategory:
247 Out <<
"[objc category]";
249 case Decl::ObjCProtocol:
250 Out <<
"[objc protocol]";
252 case Decl::ObjCImplementation:
253 Out <<
"[objc implementation]";
255 case Decl::ObjCCategoryImpl:
256 Out <<
"[objc categoryimpl]";
258 case Decl::LinkageSpec:
259 Out <<
"[linkage spec]";
264 case Decl::Function: {
267 Out <<
"[function] ";
269 Out <<
"<function> ";
273 bool PrintComma =
false;
274 for (
auto I : FD->parameters()) {
284 case Decl::CXXMethod: {
287 Out <<
"[c++ method] ";
288 else if (D->isImplicit())
289 Out <<
"(c++ method) ";
291 Out <<
"<c++ method> ";
295 bool PrintComma =
false;
307 const DeclContext* LexicalDC = D->getLexicalDeclContext();
308 if (SemaDC != LexicalDC)
309 Out <<
" [[" << SemaDC <<
"]]";
313 case Decl::CXXConstructor: {
316 Out <<
"[c++ ctor] ";
317 else if (D->isImplicit())
318 Out <<
"(c++ ctor) ";
320 Out <<
"<c++ ctor> ";
324 bool PrintComma =
false;
336 const DeclContext* LexicalDC = D->getLexicalDeclContext();
337 if (SemaDC != LexicalDC)
338 Out <<
" [[" << SemaDC <<
"]]";
341 case Decl::CXXDestructor: {
344 Out <<
"[c++ dtor] ";
345 else if (D->isImplicit())
346 Out <<
"(c++ dtor) ";
348 Out <<
"<c++ dtor> ";
352 const DeclContext* LexicalDC = D->getLexicalDeclContext();
353 if (SemaDC != LexicalDC)
354 Out <<
" [[" << SemaDC <<
"]]";
357 case Decl::CXXConversion: {
360 Out <<
"[c++ conversion] ";
361 else if (D->isImplicit())
362 Out <<
"(c++ conversion) ";
364 Out <<
"<c++ conversion> ";
368 const DeclContext* LexicalDC = D->getLexicalDeclContext();
369 if (SemaDC != LexicalDC)
370 Out <<
" [[" << SemaDC <<
"]]";
375 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
381 for (
auto *
I : DC->decls()) {
382 for (
unsigned i = 0; i < Indentation; ++i)
387 case Decl::Namespace:
390 case Decl::CXXRecord:
391 case Decl::ObjCMethod:
392 case Decl::ObjCInterface:
393 case Decl::ObjCCategory:
394 case Decl::ObjCProtocol:
395 case Decl::ObjCImplementation:
396 case Decl::ObjCCategoryImpl:
397 case Decl::LinkageSpec:
400 case Decl::CXXMethod:
401 case Decl::CXXConstructor:
402 case Decl::CXXDestructor:
403 case Decl::CXXConversion:
409 case Decl::IndirectField: {
411 Out <<
"<IndirectField> " << *IFD <<
'\n';
416 Out <<
"<Label> " << *LD <<
'\n';
421 Out <<
"<field> " << *FD <<
'\n';
427 Out <<
"<typedef> " << *TD <<
'\n';
430 case Decl::EnumConstant: {
432 Out <<
"<enum constant> " << *ECD <<
'\n';
437 Out <<
"<var> " << *VD <<
'\n';
440 case Decl::ImplicitParam: {
442 Out <<
"<implicit parameter> " << *IPD <<
'\n';
445 case Decl::ParmVar: {
447 Out <<
"<parameter> " << *PVD <<
'\n';
450 case Decl::ObjCProperty: {
452 Out <<
"<objc property> " << *OPD <<
'\n';
455 case Decl::FunctionTemplate: {
457 Out <<
"<function template> " << *FTD <<
'\n';
460 case Decl::FileScopeAsm: {
461 Out <<
"<file-scope asm>\n";
464 case Decl::UsingDirective: {
465 Out <<
"<using directive>\n";
468 case Decl::NamespaceAlias: {
470 Out <<
"<namespace alias> " << *NAD <<
'\n';
473 case Decl::ClassTemplate: {
475 Out <<
"<class template> " << *CTD <<
'\n';
478 case Decl::OMPThreadPrivate: {
479 Out <<
"<omp threadprivate> " <<
'"' <<
I <<
"\"\n";
483 Out <<
"DeclKind: " << DK <<
'"' <<
I <<
"\"\n";
484 llvm_unreachable(
"decl unhandled");
489 return llvm::make_unique<DeclContextPrinter>();
Defines the clang::ASTContext interface.
FunctionDecl - An instance of this class is created to represent a function declaration or definition...
ASTConsumer - This is an abstract interface that should be implemented by clients that read ASTs...
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...
EnumConstantDecl - An instance of this object exists for each enum constant that is defined...
Defines the SourceManager interface.
NamespaceDecl - Represent a C++ namespace.
Represents a C++ constructor within a class.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
ParmVarDecl - Represents a parameter to a function.
RecordDecl - Represents a struct/union/class.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
FieldDecl - An instance of this class is created by Sema::ActOnField to represent a member of a struc...
bool isCompleteDefinition() const
isCompleteDefinition - Return true if this decl has its body fully specified.
Print DeclContext and their Decls.
A class that does preordor or postorder depth-first traversal on the entire Clang AST and visits each...
detail::InMemoryDirectory::const_iterator I
Represents a C++ destructor within a class.
TranslationUnitDecl * getTranslationUnitDecl() const
virtual void HandleTranslationUnit(ASTContext &Ctx)
HandleTranslationUnit - This method is called when the ASTs for entire translation unit have been par...
Represents a C++ conversion function within a class.
bool doesThisDeclarationHaveABody() const
doesThisDeclarationHaveABody - Returns whether this specific declaration of the function has a body -...
LabelDecl - Represents the declaration of a label.
Represents a static or instance method of a struct/union/class.
Represents one property declaration in an Objective-C interface.
unsigned TypeAlias
Whether this template specialization type is a substituted type alias.
void printQualifiedName(raw_ostream &OS) const
printQualifiedName - Returns human-readable qualified name for declaration, like A::B::i, for i being member of namespace A::B.
Base class for declarations which introduce a typedef-name.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
IndirectFieldDecl - An instance of this class is created to represent a field injected from an anonym...
EnumDecl - Represents an enum.
detail::InMemoryDirectory::const_iterator E
Defines the Diagnostic-related interfaces.
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.
The parameter type of a method or function.
Declaration of a class template.
TranslationUnitDecl - The top declaration context.
std::unique_ptr< ASTConsumer > CreateASTDumper(StringRef FilterString, bool DumpDecls, bool DumpLookups)
std::unique_ptr< ASTConsumer > CreateASTPrinter(std::unique_ptr< raw_ostream > OS, StringRef FilterString)
NamedDecl - This represents a decl with a name.
Represents a C++ namespace alias.
Declaration of a template function.