]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - contrib/llvm/tools/clang/lib/Frontend/ASTConsumers.cpp
Merge llvm, clang, compiler-rt, libc++, libunwind, lld, lldb and openmp
[FreeBSD/FreeBSD.git] / contrib / llvm / tools / clang / lib / Frontend / ASTConsumers.cpp
1 //===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // AST Consumer Implementations.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "clang/Frontend/ASTConsumers.h"
15 #include "clang/AST/AST.h"
16 #include "clang/AST/ASTConsumer.h"
17 #include "clang/AST/ASTContext.h"
18 #include "clang/AST/PrettyPrinter.h"
19 #include "clang/AST/RecordLayout.h"
20 #include "clang/AST/RecursiveASTVisitor.h"
21 #include "clang/Basic/Diagnostic.h"
22 #include "clang/Basic/SourceManager.h"
23 #include "llvm/Support/Path.h"
24 #include "llvm/Support/Timer.h"
25 #include "llvm/Support/raw_ostream.h"
26 using namespace clang;
27
28 //===----------------------------------------------------------------------===//
29 /// ASTPrinter - Pretty-printer and dumper of ASTs
30
31 namespace {
32   class ASTPrinter : public ASTConsumer,
33                      public RecursiveASTVisitor<ASTPrinter> {
34     typedef RecursiveASTVisitor<ASTPrinter> base;
35
36   public:
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) {}
42
43     void HandleTranslationUnit(ASTContext &Context) override {
44       TranslationUnitDecl *D = Context.getTranslationUnitDecl();
45
46       if (FilterString.empty())
47         return print(D);
48
49       TraverseDecl(D);
50     }
51
52     bool shouldWalkTypesOfTypeLocs() const { return false; }
53
54     bool TraverseDecl(Decl *D) {
55       if (D && filterMatches(D)) {
56         bool ShowColors = Out.has_colors();
57         if (ShowColors)
58           Out.changeColor(raw_ostream::BLUE);
59         Out << (OutputKind != Print ? "Dumping " : "Printing ") << getName(D)
60             << ":\n";
61         if (ShowColors)
62           Out.resetColor();
63         print(D);
64         Out << "\n";
65         // Don't traverse child nodes to avoid output duplication.
66         return true;
67       }
68       return base::TraverseDecl(D);
69     }
70
71   private:
72     std::string getName(Decl *D) {
73       if (isa<NamedDecl>(D))
74         return cast<NamedDecl>(D)->getQualifiedNameAsString();
75       return "";
76     }
77     bool filterMatches(Decl *D) {
78       return getName(D).find(FilterString) != std::string::npos;
79     }
80     void print(Decl *D) {
81       if (DumpLookups) {
82         if (DeclContext *DC = dyn_cast<DeclContext>(D)) {
83           if (DC == DC->getPrimaryContext())
84             DC->dumpLookups(Out, OutputKind != None, OutputKind == DumpFull);
85           else
86             Out << "Lookup map is in primary DeclContext "
87                 << DC->getPrimaryContext() << "\n";
88         } else
89           Out << "Not a DeclContext\n";
90       } else if (OutputKind == Print) {
91         PrintingPolicy Policy(D->getASTContext().getLangOpts());
92         D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
93       } else if (OutputKind != None)
94         D->dump(Out, OutputKind == DumpFull);
95     }
96
97     raw_ostream &Out;
98     std::unique_ptr<raw_ostream> OwnedOut;
99
100     /// How to output individual declarations.
101     Kind OutputKind;
102
103     /// Which declarations or DeclContexts to display.
104     std::string FilterString;
105
106     /// Whether the primary output is lookup results or declarations. Individual
107     /// results will be output with a format determined by OutputKind. This is
108     /// incompatible with OutputKind == Print.
109     bool DumpLookups;
110   };
111
112   class ASTDeclNodeLister : public ASTConsumer,
113                      public RecursiveASTVisitor<ASTDeclNodeLister> {
114   public:
115     ASTDeclNodeLister(raw_ostream *Out = nullptr)
116         : Out(Out ? *Out : llvm::outs()) {}
117
118     void HandleTranslationUnit(ASTContext &Context) override {
119       TraverseDecl(Context.getTranslationUnitDecl());
120     }
121
122     bool shouldWalkTypesOfTypeLocs() const { return false; }
123
124     bool VisitNamedDecl(NamedDecl *D) {
125       D->printQualifiedName(Out);
126       Out << '\n';
127       return true;
128     }
129
130   private:
131     raw_ostream &Out;
132   };
133 } // end anonymous namespace
134
135 std::unique_ptr<ASTConsumer>
136 clang::CreateASTPrinter(std::unique_ptr<raw_ostream> Out,
137                         StringRef FilterString) {
138   return llvm::make_unique<ASTPrinter>(std::move(Out), ASTPrinter::Print,
139                                        FilterString);
140 }
141
142 std::unique_ptr<ASTConsumer>
143 clang::CreateASTDumper(std::unique_ptr<raw_ostream> Out,
144                        StringRef FilterString,
145                        bool DumpDecls,
146                        bool Deserialize,
147                        bool DumpLookups) {
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 :
152                                        ASTPrinter::None,
153                                        FilterString, DumpLookups);
154 }
155
156 std::unique_ptr<ASTConsumer> clang::CreateASTDeclNodeLister() {
157   return llvm::make_unique<ASTDeclNodeLister>(nullptr);
158 }
159
160 //===----------------------------------------------------------------------===//
161 /// ASTViewer - AST Visualization
162
163 namespace {
164   class ASTViewer : public ASTConsumer {
165     ASTContext *Context;
166   public:
167     void Initialize(ASTContext &Context) override {
168       this->Context = &Context;
169     }
170
171     bool HandleTopLevelDecl(DeclGroupRef D) override {
172       for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
173         HandleTopLevelSingleDecl(*I);
174       return true;
175     }
176
177     void HandleTopLevelSingleDecl(Decl *D);
178   };
179 }
180
181 void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
182   if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
183     D->print(llvm::errs());
184
185     if (Stmt *Body = D->getBody()) {
186       llvm::errs() << '\n';
187       Body->viewAST();
188       llvm::errs() << '\n';
189     }
190   }
191 }
192
193 std::unique_ptr<ASTConsumer> clang::CreateASTViewer() {
194   return llvm::make_unique<ASTViewer>();
195 }