1193326Sed//===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//
2193326Sed//
3193326Sed//                     The LLVM Compiler Infrastructure
4193326Sed//
5193326Sed// This file is distributed under the University of Illinois Open Source
6193326Sed// License. See LICENSE.TXT for details.
7193326Sed//
8193326Sed//===----------------------------------------------------------------------===//
9193326Sed//
10193326Sed// AST Consumer Implementations.
11193326Sed//
12193326Sed//===----------------------------------------------------------------------===//
13193326Sed
14193326Sed#include "clang/Frontend/ASTConsumers.h"
15193326Sed#include "clang/AST/AST.h"
16193326Sed#include "clang/AST/ASTConsumer.h"
17193326Sed#include "clang/AST/ASTContext.h"
18239462Sdim#include "clang/AST/PrettyPrinter.h"
19198092Srdivacky#include "clang/AST/RecordLayout.h"
20239462Sdim#include "clang/AST/RecursiveASTVisitor.h"
21249423Sdim#include "clang/Basic/Diagnostic.h"
22249423Sdim#include "clang/Basic/FileManager.h"
23249423Sdim#include "clang/Basic/SourceManager.h"
24249423Sdim#include "llvm/IR/Module.h"
25239462Sdim#include "llvm/Support/Path.h"
26249423Sdim#include "llvm/Support/Timer.h"
27239462Sdim#include "llvm/Support/raw_ostream.h"
28193326Sedusing namespace clang;
29193326Sed
30193326Sed//===----------------------------------------------------------------------===//
31193326Sed/// ASTPrinter - Pretty-printer and dumper of ASTs
32193326Sed
33193326Sednamespace {
34239462Sdim  class ASTPrinter : public ASTConsumer,
35239462Sdim                     public RecursiveASTVisitor<ASTPrinter> {
36239462Sdim    typedef RecursiveASTVisitor<ASTPrinter> base;
37239462Sdim
38239462Sdim  public:
39239462Sdim    ASTPrinter(raw_ostream *Out = NULL, bool Dump = false,
40263508Sdim               StringRef FilterString = "", bool DumpLookups = false)
41239462Sdim        : Out(Out ? *Out : llvm::outs()), Dump(Dump),
42263508Sdim          FilterString(FilterString), DumpLookups(DumpLookups) {}
43239462Sdim
44239462Sdim    virtual void HandleTranslationUnit(ASTContext &Context) {
45239462Sdim      TranslationUnitDecl *D = Context.getTranslationUnitDecl();
46239462Sdim
47263508Sdim      if (FilterString.empty())
48263508Sdim        return print(D);
49239462Sdim
50239462Sdim      TraverseDecl(D);
51239462Sdim    }
52239462Sdim
53239462Sdim    bool shouldWalkTypesOfTypeLocs() const { return false; }
54239462Sdim
55239462Sdim    bool TraverseDecl(Decl *D) {
56243830Sdim      if (D != NULL && filterMatches(D)) {
57249423Sdim        bool ShowColors = Out.has_colors();
58249423Sdim        if (ShowColors)
59249423Sdim          Out.changeColor(raw_ostream::BLUE);
60249423Sdim        Out << (Dump ? "Dumping " : "Printing ") << getName(D) << ":\n";
61249423Sdim        if (ShowColors)
62249423Sdim          Out.resetColor();
63263508Sdim        print(D);
64243830Sdim        Out << "\n";
65239462Sdim        // Don't traverse child nodes to avoid output duplication.
66239462Sdim        return true;
67239462Sdim      }
68239462Sdim      return base::TraverseDecl(D);
69239462Sdim    }
70239462Sdim
71239462Sdim  private:
72239462Sdim    std::string getName(Decl *D) {
73239462Sdim      if (isa<NamedDecl>(D))
74239462Sdim        return cast<NamedDecl>(D)->getQualifiedNameAsString();
75239462Sdim      return "";
76239462Sdim    }
77239462Sdim    bool filterMatches(Decl *D) {
78239462Sdim      return getName(D).find(FilterString) != std::string::npos;
79239462Sdim    }
80263508Sdim    void print(Decl *D) {
81263508Sdim      if (DumpLookups) {
82263508Sdim        if (DeclContext *DC = dyn_cast<DeclContext>(D))
83263508Sdim          DC->dumpLookups(Out);
84263508Sdim        else
85263508Sdim          Out << "Not a DeclContext\n";
86263508Sdim      } else if (Dump)
87263508Sdim        D->dump(Out);
88263508Sdim      else
89263508Sdim        D->print(Out, /*Indentation=*/0, /*PrintInstantiation=*/true);
90263508Sdim    }
91239462Sdim
92226633Sdim    raw_ostream &Out;
93193326Sed    bool Dump;
94239462Sdim    std::string FilterString;
95263508Sdim    bool DumpLookups;
96239462Sdim  };
97198092Srdivacky
98239462Sdim  class ASTDeclNodeLister : public ASTConsumer,
99239462Sdim                     public RecursiveASTVisitor<ASTDeclNodeLister> {
100193326Sed  public:
101239462Sdim    ASTDeclNodeLister(raw_ostream *Out = NULL)
102239462Sdim        : Out(Out ? *Out : llvm::outs()) {}
103198092Srdivacky
104193326Sed    virtual void HandleTranslationUnit(ASTContext &Context) {
105239462Sdim      TraverseDecl(Context.getTranslationUnitDecl());
106193326Sed    }
107239462Sdim
108239462Sdim    bool shouldWalkTypesOfTypeLocs() const { return false; }
109239462Sdim
110239462Sdim    virtual bool VisitNamedDecl(NamedDecl *D) {
111249423Sdim      D->printQualifiedName(Out);
112249423Sdim      Out << '\n';
113239462Sdim      return true;
114239462Sdim    }
115239462Sdim
116239462Sdim  private:
117239462Sdim    raw_ostream &Out;
118193326Sed  };
119193326Sed} // end anonymous namespace
120193326Sed
121239462SdimASTConsumer *clang::CreateASTPrinter(raw_ostream *Out,
122239462Sdim                                     StringRef FilterString) {
123239462Sdim  return new ASTPrinter(Out, /*Dump=*/ false, FilterString);
124193326Sed}
125193326Sed
126263508SdimASTConsumer *clang::CreateASTDumper(StringRef FilterString, bool DumpLookups) {
127263508Sdim  return new ASTPrinter(0, /*Dump=*/ true, FilterString, DumpLookups);
128193326Sed}
129193326Sed
130239462SdimASTConsumer *clang::CreateASTDeclNodeLister() {
131239462Sdim  return new ASTDeclNodeLister(0);
132239462Sdim}
133239462Sdim
134193326Sed//===----------------------------------------------------------------------===//
135193326Sed/// ASTViewer - AST Visualization
136193326Sed
137193326Sednamespace {
138193326Sed  class ASTViewer : public ASTConsumer {
139193326Sed    ASTContext *Context;
140193326Sed  public:
141193326Sed    void Initialize(ASTContext &Context) {
142193326Sed      this->Context = &Context;
143193326Sed    }
144193326Sed
145234353Sdim    virtual bool HandleTopLevelDecl(DeclGroupRef D) {
146193326Sed      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
147193326Sed        HandleTopLevelSingleDecl(*I);
148234353Sdim      return true;
149193326Sed    }
150198092Srdivacky
151193326Sed    void HandleTopLevelSingleDecl(Decl *D);
152193326Sed  };
153193326Sed}
154193326Sed
155193326Sedvoid ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
156210299Sed  if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
157210299Sed    D->print(llvm::errs());
158210299Sed
159210299Sed    if (Stmt *Body = D->getBody()) {
160198092Srdivacky      llvm::errs() << '\n';
161198092Srdivacky      Body->viewAST();
162198092Srdivacky      llvm::errs() << '\n';
163193326Sed    }
164193326Sed  }
165193326Sed}
166193326Sed
167193326Sed
168193326SedASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); }
169193326Sed
170193326Sed//===----------------------------------------------------------------------===//
171193326Sed/// DeclContextPrinter - Decl and DeclContext Visualization
172193326Sed
173193326Sednamespace {
174193326Sed
175193326Sedclass DeclContextPrinter : public ASTConsumer {
176226633Sdim  raw_ostream& Out;
177193326Sedpublic:
178193326Sed  DeclContextPrinter() : Out(llvm::errs()) {}
179193326Sed
180193326Sed  void HandleTranslationUnit(ASTContext &C) {
181193326Sed    PrintDeclContext(C.getTranslationUnitDecl(), 4);
182193326Sed  }
183193326Sed
184193326Sed  void PrintDeclContext(const DeclContext* DC, unsigned Indentation);
185193326Sed};
186193326Sed}  // end anonymous namespace
187193326Sed
188198092Srdivackyvoid DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
189193326Sed                                          unsigned Indentation) {
190193326Sed  // Print DeclContext name.
191193326Sed  switch (DC->getDeclKind()) {
192193326Sed  case Decl::TranslationUnit:
193193326Sed    Out << "[translation unit] " << DC;
194193326Sed    break;
195193326Sed  case Decl::Namespace: {
196193326Sed    Out << "[namespace] ";
197193326Sed    const NamespaceDecl* ND = cast<NamespaceDecl>(DC);
198226633Sdim    Out << *ND;
199193326Sed    break;
200193326Sed  }
201193326Sed  case Decl::Enum: {
202193326Sed    const EnumDecl* ED = cast<EnumDecl>(DC);
203226633Sdim    if (ED->isCompleteDefinition())
204193326Sed      Out << "[enum] ";
205193326Sed    else
206193326Sed      Out << "<enum> ";
207226633Sdim    Out << *ED;
208193326Sed    break;
209193326Sed  }
210193326Sed  case Decl::Record: {
211193326Sed    const RecordDecl* RD = cast<RecordDecl>(DC);
212226633Sdim    if (RD->isCompleteDefinition())
213193326Sed      Out << "[struct] ";
214193326Sed    else
215193326Sed      Out << "<struct> ";
216226633Sdim    Out << *RD;
217193326Sed    break;
218193326Sed  }
219193326Sed  case Decl::CXXRecord: {
220193326Sed    const CXXRecordDecl* RD = cast<CXXRecordDecl>(DC);
221226633Sdim    if (RD->isCompleteDefinition())
222193326Sed      Out << "[class] ";
223193326Sed    else
224193326Sed      Out << "<class> ";
225226633Sdim    Out << *RD << ' ' << DC;
226193326Sed    break;
227193326Sed  }
228193326Sed  case Decl::ObjCMethod:
229193326Sed    Out << "[objc method]";
230193326Sed    break;
231193326Sed  case Decl::ObjCInterface:
232193326Sed    Out << "[objc interface]";
233193326Sed    break;
234193326Sed  case Decl::ObjCCategory:
235193326Sed    Out << "[objc category]";
236193326Sed    break;
237193326Sed  case Decl::ObjCProtocol:
238193326Sed    Out << "[objc protocol]";
239193326Sed    break;
240193326Sed  case Decl::ObjCImplementation:
241193326Sed    Out << "[objc implementation]";
242193326Sed    break;
243193326Sed  case Decl::ObjCCategoryImpl:
244193326Sed    Out << "[objc categoryimpl]";
245193326Sed    break;
246193326Sed  case Decl::LinkageSpec:
247193326Sed    Out << "[linkage spec]";
248193326Sed    break;
249193326Sed  case Decl::Block:
250193326Sed    Out << "[block]";
251193326Sed    break;
252193326Sed  case Decl::Function: {
253193326Sed    const FunctionDecl* FD = cast<FunctionDecl>(DC);
254223017Sdim    if (FD->doesThisDeclarationHaveABody())
255193326Sed      Out << "[function] ";
256193326Sed    else
257193326Sed      Out << "<function> ";
258226633Sdim    Out << *FD;
259193326Sed    // Print the parameters.
260193326Sed    Out << "(";
261193326Sed    bool PrintComma = false;
262198092Srdivacky    for (FunctionDecl::param_const_iterator I = FD->param_begin(),
263193326Sed           E = FD->param_end(); I != E; ++I) {
264193326Sed      if (PrintComma)
265193326Sed        Out << ", ";
266193326Sed      else
267193326Sed        PrintComma = true;
268226633Sdim      Out << **I;
269193326Sed    }
270193326Sed    Out << ")";
271193326Sed    break;
272193326Sed  }
273193326Sed  case Decl::CXXMethod: {
274193326Sed    const CXXMethodDecl* D = cast<CXXMethodDecl>(DC);
275194613Sed    if (D->isOutOfLine())
276193326Sed      Out << "[c++ method] ";
277193326Sed    else if (D->isImplicit())
278193326Sed      Out << "(c++ method) ";
279193326Sed    else
280193326Sed      Out << "<c++ method> ";
281226633Sdim    Out << *D;
282193326Sed    // Print the parameters.
283193326Sed    Out << "(";
284193326Sed    bool PrintComma = false;
285198092Srdivacky    for (FunctionDecl::param_const_iterator I = D->param_begin(),
286193326Sed           E = D->param_end(); I != E; ++I) {
287193326Sed      if (PrintComma)
288193326Sed        Out << ", ";
289193326Sed      else
290193326Sed        PrintComma = true;
291226633Sdim      Out << **I;
292193326Sed    }
293193326Sed    Out << ")";
294193326Sed
295193326Sed    // Check the semantic DeclContext.
296193326Sed    const DeclContext* SemaDC = D->getDeclContext();
297193326Sed    const DeclContext* LexicalDC = D->getLexicalDeclContext();
298193326Sed    if (SemaDC != LexicalDC)
299193326Sed      Out << " [[" << SemaDC << "]]";
300193326Sed
301193326Sed    break;
302193326Sed  }
303193326Sed  case Decl::CXXConstructor: {
304193326Sed    const CXXConstructorDecl* D = cast<CXXConstructorDecl>(DC);
305194613Sed    if (D->isOutOfLine())
306193326Sed      Out << "[c++ ctor] ";
307193326Sed    else if (D->isImplicit())
308193326Sed      Out << "(c++ ctor) ";
309193326Sed    else
310193326Sed      Out << "<c++ ctor> ";
311226633Sdim    Out << *D;
312193326Sed    // Print the parameters.
313193326Sed    Out << "(";
314193326Sed    bool PrintComma = false;
315198092Srdivacky    for (FunctionDecl::param_const_iterator I = D->param_begin(),
316193326Sed           E = D->param_end(); I != E; ++I) {
317193326Sed      if (PrintComma)
318193326Sed        Out << ", ";
319193326Sed      else
320193326Sed        PrintComma = true;
321226633Sdim      Out << **I;
322193326Sed    }
323193326Sed    Out << ")";
324193326Sed
325193326Sed    // Check the semantic DC.
326193326Sed    const DeclContext* SemaDC = D->getDeclContext();
327193326Sed    const DeclContext* LexicalDC = D->getLexicalDeclContext();
328193326Sed    if (SemaDC != LexicalDC)
329193326Sed      Out << " [[" << SemaDC << "]]";
330193326Sed    break;
331193326Sed  }
332193326Sed  case Decl::CXXDestructor: {
333193326Sed    const CXXDestructorDecl* D = cast<CXXDestructorDecl>(DC);
334194613Sed    if (D->isOutOfLine())
335193326Sed      Out << "[c++ dtor] ";
336193326Sed    else if (D->isImplicit())
337193326Sed      Out << "(c++ dtor) ";
338193326Sed    else
339193326Sed      Out << "<c++ dtor> ";
340226633Sdim    Out << *D;
341193326Sed    // Check the semantic DC.
342193326Sed    const DeclContext* SemaDC = D->getDeclContext();
343193326Sed    const DeclContext* LexicalDC = D->getLexicalDeclContext();
344193326Sed    if (SemaDC != LexicalDC)
345193326Sed      Out << " [[" << SemaDC << "]]";
346193326Sed    break;
347193326Sed  }
348193326Sed  case Decl::CXXConversion: {
349193326Sed    const CXXConversionDecl* D = cast<CXXConversionDecl>(DC);
350194613Sed    if (D->isOutOfLine())
351193326Sed      Out << "[c++ conversion] ";
352193326Sed    else if (D->isImplicit())
353193326Sed      Out << "(c++ conversion) ";
354193326Sed    else
355193326Sed      Out << "<c++ conversion> ";
356226633Sdim    Out << *D;
357193326Sed    // Check the semantic DC.
358193326Sed    const DeclContext* SemaDC = D->getDeclContext();
359193326Sed    const DeclContext* LexicalDC = D->getLexicalDeclContext();
360193326Sed    if (SemaDC != LexicalDC)
361193326Sed      Out << " [[" << SemaDC << "]]";
362193326Sed    break;
363193326Sed  }
364193326Sed
365193326Sed  default:
366226633Sdim    llvm_unreachable("a decl that inherits DeclContext isn't handled");
367193326Sed  }
368193326Sed
369193326Sed  Out << "\n";
370193326Sed
371193326Sed  // Print decls in the DeclContext.
372195341Sed  for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
373193326Sed       I != E; ++I) {
374193326Sed    for (unsigned i = 0; i < Indentation; ++i)
375193326Sed      Out << "  ";
376193326Sed
377193326Sed    Decl::Kind DK = I->getKind();
378193326Sed    switch (DK) {
379193326Sed    case Decl::Namespace:
380193326Sed    case Decl::Enum:
381193326Sed    case Decl::Record:
382193326Sed    case Decl::CXXRecord:
383193326Sed    case Decl::ObjCMethod:
384193326Sed    case Decl::ObjCInterface:
385198092Srdivacky    case Decl::ObjCCategory:
386193326Sed    case Decl::ObjCProtocol:
387193326Sed    case Decl::ObjCImplementation:
388193326Sed    case Decl::ObjCCategoryImpl:
389193326Sed    case Decl::LinkageSpec:
390193326Sed    case Decl::Block:
391193326Sed    case Decl::Function:
392193326Sed    case Decl::CXXMethod:
393193326Sed    case Decl::CXXConstructor:
394193326Sed    case Decl::CXXDestructor:
395193326Sed    case Decl::CXXConversion:
396193326Sed    {
397193326Sed      DeclContext* DC = cast<DeclContext>(*I);
398193326Sed      PrintDeclContext(DC, Indentation+2);
399193326Sed      break;
400193326Sed    }
401218893Sdim    case Decl::IndirectField: {
402218893Sdim      IndirectFieldDecl* IFD = cast<IndirectFieldDecl>(*I);
403226633Sdim      Out << "<IndirectField> " << *IFD << '\n';
404218893Sdim      break;
405218893Sdim    }
406218893Sdim    case Decl::Label: {
407218893Sdim      LabelDecl *LD = cast<LabelDecl>(*I);
408226633Sdim      Out << "<Label> " << *LD << '\n';
409218893Sdim      break;
410218893Sdim    }
411193326Sed    case Decl::Field: {
412218893Sdim      FieldDecl *FD = cast<FieldDecl>(*I);
413226633Sdim      Out << "<field> " << *FD << '\n';
414193326Sed      break;
415193326Sed    }
416221345Sdim    case Decl::Typedef:
417221345Sdim    case Decl::TypeAlias: {
418221345Sdim      TypedefNameDecl* TD = cast<TypedefNameDecl>(*I);
419226633Sdim      Out << "<typedef> " << *TD << '\n';
420193326Sed      break;
421193326Sed    }
422193326Sed    case Decl::EnumConstant: {
423193326Sed      EnumConstantDecl* ECD = cast<EnumConstantDecl>(*I);
424226633Sdim      Out << "<enum constant> " << *ECD << '\n';
425193326Sed      break;
426193326Sed    }
427193326Sed    case Decl::Var: {
428193326Sed      VarDecl* VD = cast<VarDecl>(*I);
429226633Sdim      Out << "<var> " << *VD << '\n';
430193326Sed      break;
431193326Sed    }
432193326Sed    case Decl::ImplicitParam: {
433193326Sed      ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(*I);
434226633Sdim      Out << "<implicit parameter> " << *IPD << '\n';
435193326Sed      break;
436193326Sed    }
437193326Sed    case Decl::ParmVar: {
438193326Sed      ParmVarDecl* PVD = cast<ParmVarDecl>(*I);
439226633Sdim      Out << "<parameter> " << *PVD << '\n';
440193326Sed      break;
441193326Sed    }
442193326Sed    case Decl::ObjCProperty: {
443193326Sed      ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(*I);
444226633Sdim      Out << "<objc property> " << *OPD << '\n';
445193326Sed      break;
446193326Sed    }
447200583Srdivacky    case Decl::FunctionTemplate: {
448200583Srdivacky      FunctionTemplateDecl* FTD = cast<FunctionTemplateDecl>(*I);
449226633Sdim      Out << "<function template> " << *FTD << '\n';
450200583Srdivacky      break;
451200583Srdivacky    }
452202379Srdivacky    case Decl::FileScopeAsm: {
453202379Srdivacky      Out << "<file-scope asm>\n";
454202379Srdivacky      break;
455202379Srdivacky    }
456202379Srdivacky    case Decl::UsingDirective: {
457202379Srdivacky      Out << "<using directive>\n";
458202379Srdivacky      break;
459202379Srdivacky    }
460202379Srdivacky    case Decl::NamespaceAlias: {
461202379Srdivacky      NamespaceAliasDecl* NAD = cast<NamespaceAliasDecl>(*I);
462226633Sdim      Out << "<namespace alias> " << *NAD << '\n';
463202379Srdivacky      break;
464202379Srdivacky    }
465202879Srdivacky    case Decl::ClassTemplate: {
466202879Srdivacky      ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(*I);
467226633Sdim      Out << "<class template> " << *CTD << '\n';
468202879Srdivacky      break;
469202879Srdivacky    }
470249423Sdim    case Decl::OMPThreadPrivate: {
471249423Sdim      Out << "<omp threadprivate> " << '"' << *I << "\"\n";
472249423Sdim      break;
473249423Sdim    }
474193326Sed    default:
475207619Srdivacky      Out << "DeclKind: " << DK << '"' << *I << "\"\n";
476226633Sdim      llvm_unreachable("decl unhandled");
477193326Sed    }
478193326Sed  }
479193326Sed}
480198092SrdivackyASTConsumer *clang::CreateDeclContextPrinter() {
481198092Srdivacky  return new DeclContextPrinter();
482193326Sed}
483