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);
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) {
92 D->
print(Out, Policy, 0,
true);
93 }
else if (OutputKind != None)
94 D->
dump(Out, OutputKind == DumpFull);
98 std::unique_ptr<raw_ostream> OwnedOut;
104 std::string FilterString;
115 ASTDeclNodeLister(raw_ostream *Out =
nullptr)
116 : Out(Out ? *Out :
llvm::outs()) {}
118 void HandleTranslationUnit(
ASTContext &Context)
override {
122 bool shouldWalkTypesOfTypeLocs()
const {
return false; }
135 std::unique_ptr<ASTConsumer>
137 StringRef FilterString) {
138 return llvm::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,
142 std::unique_ptr<ASTConsumer>
144 StringRef FilterString,
148 assert((DumpDecls || Deserialize || DumpLookups) &&
"nothing to dump");
149 return llvm::make_unique<ASTPrinter>(std::move(Out),
150 Deserialize ? ASTPrinter::DumpFull :
151 DumpDecls ? ASTPrinter::Dump :
153 FilterString, DumpLookups);
157 return llvm::make_unique<ASTDeclNodeLister>(
nullptr);
167 void Initialize(
ASTContext &Context)
override {
168 this->Context = &Context;
173 HandleTopLevelSingleDecl(*I);
177 void HandleTopLevelSingleDecl(
Decl *D);
181 void ASTViewer::HandleTopLevelSingleDecl(
Decl *D) {
182 if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
183 D->
print(llvm::errs());
186 llvm::errs() <<
'\n';
188 llvm::errs() <<
'\n';
194 return llvm::make_unique<ASTViewer>();
205 DeclContextPrinter() : Out(llvm::errs()) {}
207 void HandleTranslationUnit(
ASTContext &
C)
override {
216 unsigned Indentation) {
219 case Decl::TranslationUnit:
220 Out <<
"[translation unit] " << DC;
222 case Decl::Namespace: {
223 Out <<
"[namespace] ";
229 const EnumDecl* ED = cast<EnumDecl>(DC);
246 case Decl::CXXRecord: {
252 Out << *RD <<
' ' << DC;
255 case Decl::ObjCMethod:
256 Out <<
"[objc method]";
258 case Decl::ObjCInterface:
259 Out <<
"[objc interface]";
261 case Decl::ObjCCategory:
262 Out <<
"[objc category]";
264 case Decl::ObjCProtocol:
265 Out <<
"[objc protocol]";
267 case Decl::ObjCImplementation:
268 Out <<
"[objc implementation]";
270 case Decl::ObjCCategoryImpl:
271 Out <<
"[objc categoryimpl]";
273 case Decl::LinkageSpec:
274 Out <<
"[linkage spec]";
282 Out <<
"[function] ";
284 Out <<
"<function> ";
288 bool PrintComma =
false;
289 for (
auto I : FD->parameters()) {
299 case Decl::CXXMethod: {
302 Out <<
"[c++ method] ";
304 Out <<
"(c++ method) ";
306 Out <<
"<c++ method> ";
310 bool PrintComma =
false;
322 const DeclContext* LexicalDC = D->getLexicalDeclContext();
323 if (SemaDC != LexicalDC)
324 Out <<
" [[" << SemaDC <<
"]]";
328 case Decl::CXXConstructor: {
331 Out <<
"[c++ ctor] ";
333 Out <<
"(c++ ctor) ";
335 Out <<
"<c++ ctor> ";
339 bool PrintComma =
false;
351 const DeclContext* LexicalDC = D->getLexicalDeclContext();
352 if (SemaDC != LexicalDC)
353 Out <<
" [[" << SemaDC <<
"]]";
356 case Decl::CXXDestructor: {
359 Out <<
"[c++ dtor] ";
361 Out <<
"(c++ dtor) ";
363 Out <<
"<c++ dtor> ";
367 const DeclContext* LexicalDC = D->getLexicalDeclContext();
368 if (SemaDC != LexicalDC)
369 Out <<
" [[" << SemaDC <<
"]]";
372 case Decl::CXXConversion: {
375 Out <<
"[c++ conversion] ";
377 Out <<
"(c++ conversion) ";
379 Out <<
"<c++ conversion> ";
383 const DeclContext* LexicalDC = D->getLexicalDeclContext();
384 if (SemaDC != LexicalDC)
385 Out <<
" [[" << SemaDC <<
"]]";
389 case Decl::ClassTemplateSpecialization: {
390 const auto *CTSD = cast<ClassTemplateSpecializationDecl>(DC);
391 if (CTSD->isCompleteDefinition())
392 Out <<
"[class template specialization] ";
394 Out <<
"<class template specialization> ";
399 case Decl::ClassTemplatePartialSpecialization: {
400 const auto *CTPSD = cast<ClassTemplatePartialSpecializationDecl>(DC);
401 if (CTPSD->isCompleteDefinition())
402 Out <<
"[class template partial specialization] ";
404 Out <<
"<class template partial specialization> ";
410 llvm_unreachable(
"a decl that inherits DeclContext isn't handled");
416 for (
auto *I : DC->
decls()) {
417 for (
unsigned i = 0; i < Indentation; ++i)
422 case Decl::Namespace:
425 case Decl::CXXRecord:
426 case Decl::ObjCMethod:
427 case Decl::ObjCInterface:
428 case Decl::ObjCCategory:
429 case Decl::ObjCProtocol:
430 case Decl::ObjCImplementation:
431 case Decl::ObjCCategoryImpl:
432 case Decl::LinkageSpec:
435 case Decl::CXXMethod:
436 case Decl::CXXConstructor:
437 case Decl::CXXDestructor:
438 case Decl::CXXConversion:
439 case Decl::ClassTemplateSpecialization:
440 case Decl::ClassTemplatePartialSpecialization: {
445 case Decl::IndirectField: {
447 Out <<
"<IndirectField> " << *IFD <<
'\n';
452 Out <<
"<Label> " << *LD <<
'\n';
457 Out <<
"<field> " << *FD <<
'\n';
461 case Decl::TypeAlias: {
463 Out <<
"<typedef> " << *TD <<
'\n';
466 case Decl::EnumConstant: {
468 Out <<
"<enum constant> " << *ECD <<
'\n';
472 VarDecl* VD = cast<VarDecl>(I);
473 Out <<
"<var> " << *VD <<
'\n';
476 case Decl::ImplicitParam: {
478 Out <<
"<implicit parameter> " << *IPD <<
'\n';
481 case Decl::ParmVar: {
483 Out <<
"<parameter> " << *PVD <<
'\n';
486 case Decl::ObjCProperty: {
488 Out <<
"<objc property> " << *OPD <<
'\n';
491 case Decl::FunctionTemplate: {
493 Out <<
"<function template> " << *FTD <<
'\n';
496 case Decl::FileScopeAsm: {
497 Out <<
"<file-scope asm>\n";
500 case Decl::UsingDirective: {
501 Out <<
"<using directive>\n";
504 case Decl::NamespaceAlias: {
506 Out <<
"<namespace alias> " << *NAD <<
'\n';
509 case Decl::ClassTemplate: {
511 Out <<
"<class template> " << *CTD <<
'\n';
514 case Decl::OMPThreadPrivate: {
515 Out <<
"<omp threadprivate> " <<
'"' << I <<
"\"\n";
520 if (
const NamedDecl *ND = cast<FriendDecl>(I)->getFriendDecl())
526 Out <<
"<using> " << *cast<UsingDecl>(I) <<
"\n";
529 case Decl::UsingShadow: {
530 Out <<
"<using shadow> " << *cast<UsingShadowDecl>(I) <<
"\n";
537 case Decl::AccessSpec: {
538 Out <<
"<access specifier>\n";
541 case Decl::VarTemplate: {
542 Out <<
"<var template> " << *cast<VarTemplateDecl>(I) <<
"\n";
545 case Decl::StaticAssert: {
546 Out <<
"<static assert>\n";
550 Out <<
"DeclKind: " << DK <<
'"' << I <<
"\"\n";
551 llvm_unreachable(
"decl unhandled");
556 return llvm::make_unique<DeclContextPrinter>();
Defines the clang::ASTContext interface.
Represents 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...
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.
Represent a C++ namespace.
constexpr XRayInstrMask Function
Represents a C++ constructor within a class.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Represents a variable declaration or definition.
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Describes how types, statements, expressions, and declarations should be printed. ...
Represents a parameter to a function.
std::string getName(ArrayRef< StringRef > Parts) const
Get the platform-specific name separator.
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 ...
Represents a member of a struct/union/class.
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...
std::unique_ptr< ASTConsumer > CreateASTDumper(std::unique_ptr< raw_ostream > OS, StringRef FilterString, bool DumpDecls, bool Deserialize, bool DumpLookups)
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
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
Represents a C++ conversion function within a class.
Decl::Kind getDeclKind() const
ASTContext & getASTContext() const LLVM_READONLY
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...
Represents a field injected from an anonymous union/struct into the parent scope. ...
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.
Kind
Lists the kind of concrete classes of Decl.
The top declaration context.
std::unique_ptr< ASTConsumer > CreateASTPrinter(std::unique_ptr< raw_ostream > OS, StringRef FilterString)
This represents a decl that may have a name.
Represents a C++ namespace alias.
const LangOptions & getLangOpts() const
Declaration of a template function.