23 #include "llvm/Support/Path.h" 24 #include "llvm/Support/Timer.h" 25 #include "llvm/Support/raw_ostream.h" 26 using namespace clang;
37 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) {}
43 void HandleTranslationUnit(
ASTContext &Context)
override {
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 << (OutputKind != Print ?
"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, OutputKind != None, OutputKind == DumpFull);
86 Out <<
"Lookup map is in primary DeclContext " 87 << DC->getPrimaryContext() <<
"\n";
89 Out <<
"Not a DeclContext\n";
90 }
else if (OutputKind == Print)
91 D->
print(Out, 0,
true);
92 else if (OutputKind != None)
93 D->
dump(Out, OutputKind == DumpFull);
97 std::unique_ptr<raw_ostream> OwnedOut;
103 std::string FilterString;
114 ASTDeclNodeLister(raw_ostream *Out =
nullptr)
115 : Out(Out ? *Out :
llvm::outs()) {}
117 void HandleTranslationUnit(
ASTContext &Context)
override {
121 bool shouldWalkTypesOfTypeLocs()
const {
return false; }
134 std::unique_ptr<ASTConsumer>
136 StringRef FilterString) {
137 return llvm::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,
145 assert((DumpDecls || Deserialize || DumpLookups) &&
"nothing to dump");
146 return llvm::make_unique<ASTPrinter>(
nullptr,
147 Deserialize ? ASTPrinter::DumpFull :
148 DumpDecls ? ASTPrinter::Dump :
150 FilterString, DumpLookups);
154 return llvm::make_unique<ASTDeclNodeLister>(
nullptr);
164 void Initialize(
ASTContext &Context)
override {
165 this->Context = &Context;
170 HandleTopLevelSingleDecl(*I);
174 void HandleTopLevelSingleDecl(
Decl *D);
178 void ASTViewer::HandleTopLevelSingleDecl(
Decl *D) {
179 if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
180 D->
print(llvm::errs());
183 llvm::errs() <<
'\n';
185 llvm::errs() <<
'\n';
191 return llvm::make_unique<ASTViewer>();
202 DeclContextPrinter() : Out(llvm::errs()) {}
204 void HandleTranslationUnit(
ASTContext &
C)
override {
213 unsigned Indentation) {
216 case Decl::TranslationUnit:
217 Out <<
"[translation unit] " << DC;
219 case Decl::Namespace: {
220 Out <<
"[namespace] ";
226 const EnumDecl* ED = cast<EnumDecl>(DC);
243 case Decl::CXXRecord: {
249 Out << *RD <<
' ' << DC;
252 case Decl::ObjCMethod:
253 Out <<
"[objc method]";
255 case Decl::ObjCInterface:
256 Out <<
"[objc interface]";
258 case Decl::ObjCCategory:
259 Out <<
"[objc category]";
261 case Decl::ObjCProtocol:
262 Out <<
"[objc protocol]";
264 case Decl::ObjCImplementation:
265 Out <<
"[objc implementation]";
267 case Decl::ObjCCategoryImpl:
268 Out <<
"[objc categoryimpl]";
270 case Decl::LinkageSpec:
271 Out <<
"[linkage spec]";
276 case Decl::Function: {
279 Out <<
"[function] ";
281 Out <<
"<function> ";
285 bool PrintComma =
false;
286 for (
auto I : FD->parameters()) {
296 case Decl::CXXMethod: {
299 Out <<
"[c++ method] ";
301 Out <<
"(c++ method) ";
303 Out <<
"<c++ method> ";
307 bool PrintComma =
false;
319 const DeclContext* LexicalDC = D->getLexicalDeclContext();
320 if (SemaDC != LexicalDC)
321 Out <<
" [[" << SemaDC <<
"]]";
325 case Decl::CXXConstructor: {
328 Out <<
"[c++ ctor] ";
330 Out <<
"(c++ ctor) ";
332 Out <<
"<c++ ctor> ";
336 bool PrintComma =
false;
348 const DeclContext* LexicalDC = D->getLexicalDeclContext();
349 if (SemaDC != LexicalDC)
350 Out <<
" [[" << SemaDC <<
"]]";
353 case Decl::CXXDestructor: {
356 Out <<
"[c++ dtor] ";
358 Out <<
"(c++ dtor) ";
360 Out <<
"<c++ dtor> ";
364 const DeclContext* LexicalDC = D->getLexicalDeclContext();
365 if (SemaDC != LexicalDC)
366 Out <<
" [[" << SemaDC <<
"]]";
369 case Decl::CXXConversion: {
372 Out <<
"[c++ conversion] ";
374 Out <<
"(c++ conversion) ";
376 Out <<
"<c++ conversion> ";
380 const DeclContext* LexicalDC = D->getLexicalDeclContext();
381 if (SemaDC != LexicalDC)
382 Out <<
" [[" << SemaDC <<
"]]";
386 case Decl::ClassTemplateSpecialization: {
387 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(DC);
388 if (CTSD->isCompleteDefinition())
389 Out <<
"[class template specialization] ";
391 Out <<
"<class template specialization> ";
396 case Decl::ClassTemplatePartialSpecialization: {
397 const auto *CTPSD = cast<ClassTemplatePartialSpecializationDecl>(DC);
398 if (CTPSD->isCompleteDefinition())
399 Out <<
"[class template partial specialization] ";
401 Out <<
"<class template partial specialization> ";
407 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
413 for (
auto *I : DC->
decls()) {
414 for (
unsigned i = 0; i < Indentation; ++i)
419 case Decl::Namespace:
422 case Decl::CXXRecord:
423 case Decl::ObjCMethod:
424 case Decl::ObjCInterface:
425 case Decl::ObjCCategory:
426 case Decl::ObjCProtocol:
427 case Decl::ObjCImplementation:
428 case Decl::ObjCCategoryImpl:
429 case Decl::LinkageSpec:
432 case Decl::CXXMethod:
433 case Decl::CXXConstructor:
434 case Decl::CXXDestructor:
435 case Decl::CXXConversion:
436 case Decl::ClassTemplateSpecialization:
437 case Decl::ClassTemplatePartialSpecialization: {
442 case Decl::IndirectField: {
444 Out <<
"<IndirectField> " << *IFD <<
'\n';
449 Out <<
"<Label> " << *LD <<
'\n';
454 Out <<
"<field> " << *FD <<
'\n';
458 case Decl::TypeAlias: {
460 Out <<
"<typedef> " << *TD <<
'\n';
463 case Decl::EnumConstant: {
465 Out <<
"<enum constant> " << *ECD <<
'\n';
469 VarDecl* VD = cast<VarDecl>(I);
470 Out <<
"<var> " << *VD <<
'\n';
473 case Decl::ImplicitParam: {
475 Out <<
"<implicit parameter> " << *IPD <<
'\n';
478 case Decl::ParmVar: {
480 Out <<
"<parameter> " << *PVD <<
'\n';
483 case Decl::ObjCProperty: {
485 Out <<
"<objc property> " << *OPD <<
'\n';
488 case Decl::FunctionTemplate: {
490 Out <<
"<function template> " << *FTD <<
'\n';
493 case Decl::FileScopeAsm: {
494 Out <<
"<file-scope asm>\n";
497 case Decl::UsingDirective: {
498 Out <<
"<using directive>\n";
501 case Decl::NamespaceAlias: {
503 Out <<
"<namespace alias> " << *NAD <<
'\n';
506 case Decl::ClassTemplate: {
508 Out <<
"<class template> " << *CTD <<
'\n';
511 case Decl::OMPThreadPrivate: {
512 Out <<
"<omp threadprivate> " <<
'"' << I <<
"\"\n";
517 if (
const NamedDecl *ND = cast<FriendDecl>(I)->getFriendDecl())
523 Out <<
"<using> " << *cast<UsingDecl>(I) <<
"\n";
526 case Decl::UsingShadow: {
527 Out <<
"<using shadow> " << *cast<UsingShadowDecl>(I) <<
"\n";
534 case Decl::AccessSpec: {
535 Out <<
"<access specifier>\n";
538 case Decl::VarTemplate: {
539 Out <<
"<var template> " << *cast<VarTemplateDecl>(I) <<
"\n";
542 case Decl::StaticAssert: {
543 Out <<
"<static assert>\n";
547 Out <<
"DeclKind: " << DK <<
'"' << I <<
"\"\n";
548 llvm_unreachable(
"decl unhandled");
553 return llvm::make_unique<DeclContextPrinter>();
Defines the clang::ASTContext interface.
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...
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
DominatorTree GraphTraits specialization so the DominatorTree can be iterable by generic graph iterat...
Stmt - This represents one statement.
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.
Decl - This represents one declaration (or definition), e.g.
NamespaceDecl - Represent a C++ namespace.
Represents a C++ constructor within a class.
bool isCompleteDefinition() const
isCompleteDefinition - Return true if this decl has its body fully specified.
VarDecl - An instance of this class is created to represent a variable declaration or definition...
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
ParmVarDecl - Represents a parameter to a function.
std::unique_ptr< ASTConsumer > CreateASTDumper(StringRef FilterString, bool DumpDecls, bool Deserialize, bool DumpLookups)
RecordDecl - Represents a struct/union/class.
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
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...
Print DeclContext and their Decls.
Defines the Diagnostic-related interfaces.
A class that does preorder or postorder depth-first traversal on the entire Clang AST and visits each...
Represents a C++ destructor within a class.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
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.
Represents a C++ conversion function within a class.
Decl::Kind getDeclKind() const
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.
Base class for declarations which introduce a typedef-name.
Dataflow Directional Tag Classes.
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.
std::unique_ptr< ASTConsumer > CreateDeclContextPrinter()
std::unique_ptr< ASTConsumer > CreateASTViewer()
std::unique_ptr< ASTConsumer > CreateASTDeclNodeLister()
TranslationUnitDecl * getTranslationUnitDecl() const
Represents a C++ struct/union/class.
The parameter type of a method or function.
Declaration of a class template.
bool doesThisDeclarationHaveABody() const
Returns whether this specific declaration of the function has a body - that is, if it is a non-delete...
Kind
Lists the kind of concrete classes of Decl.
TranslationUnitDecl - The top declaration context.
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.