ASTConsumers.cpp revision 218893
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"
15198092Srdivacky#include "clang/Frontend/DocumentXML.h"
16193326Sed#include "clang/Basic/Diagnostic.h"
17193326Sed#include "clang/Basic/SourceManager.h"
18193326Sed#include "clang/Basic/FileManager.h"
19193326Sed#include "clang/AST/AST.h"
20193326Sed#include "clang/AST/ASTConsumer.h"
21193326Sed#include "clang/AST/ASTContext.h"
22198092Srdivacky#include "clang/AST/RecordLayout.h"
23193326Sed#include "clang/AST/PrettyPrinter.h"
24193326Sed#include "llvm/Module.h"
25193326Sed#include "llvm/Support/Timer.h"
26193326Sed#include "llvm/Support/raw_ostream.h"
27218893Sdim#include "llvm/Support/Path.h"
28193326Sedusing namespace clang;
29193326Sed
30193326Sed//===----------------------------------------------------------------------===//
31193326Sed/// ASTPrinter - Pretty-printer and dumper of ASTs
32193326Sed
33193326Sednamespace {
34193326Sed  class ASTPrinter : public ASTConsumer {
35193326Sed    llvm::raw_ostream &Out;
36193326Sed    bool Dump;
37198092Srdivacky
38193326Sed  public:
39198092Srdivacky    ASTPrinter(llvm::raw_ostream* o = NULL, bool Dump = false)
40212904Sdim      : Out(o? *o : llvm::outs()), Dump(Dump) { }
41198092Srdivacky
42193326Sed    virtual void HandleTranslationUnit(ASTContext &Context) {
43193326Sed      PrintingPolicy Policy = Context.PrintingPolicy;
44193326Sed      Policy.Dump = Dump;
45195341Sed      Context.getTranslationUnitDecl()->print(Out, Policy);
46193326Sed    }
47193326Sed  };
48193326Sed} // end anonymous namespace
49193326Sed
50193326SedASTConsumer *clang::CreateASTPrinter(llvm::raw_ostream* out) {
51193326Sed  return new ASTPrinter(out);
52193326Sed}
53193326Sed
54193326Sed//===----------------------------------------------------------------------===//
55193326Sed/// ASTPrinterXML - XML-printer of ASTs
56193326Sed
57193326Sednamespace {
58193326Sed  class ASTPrinterXML : public ASTConsumer {
59193326Sed    DocumentXML         Doc;
60193326Sed
61193326Sed  public:
62193326Sed    ASTPrinterXML(llvm::raw_ostream& o) : Doc("CLANG_XML", o) {}
63198092Srdivacky
64193326Sed    void Initialize(ASTContext &Context) {
65193326Sed      Doc.initialize(Context);
66193326Sed    }
67193326Sed
68193326Sed    virtual void HandleTranslationUnit(ASTContext &Ctx) {
69193326Sed      Doc.addSubNode("TranslationUnit");
70198092Srdivacky      for (DeclContext::decl_iterator
71195341Sed             D = Ctx.getTranslationUnitDecl()->decls_begin(),
72195341Sed             DEnd = Ctx.getTranslationUnitDecl()->decls_end();
73198092Srdivacky           D != DEnd;
74193326Sed           ++D)
75193326Sed        Doc.PrintDecl(*D);
76193326Sed      Doc.toParent();
77193326Sed      Doc.finalize();
78193326Sed    }
79193326Sed  };
80193326Sed} // end anonymous namespace
81193326Sed
82193326Sed
83193326SedASTConsumer *clang::CreateASTPrinterXML(llvm::raw_ostream* out) {
84193326Sed  return new ASTPrinterXML(out ? *out : llvm::outs());
85193326Sed}
86198092Srdivacky
87198092SrdivackyASTConsumer *clang::CreateASTDumper() {
88198092Srdivacky  return new ASTPrinter(0, true);
89193326Sed}
90193326Sed
91193326Sed//===----------------------------------------------------------------------===//
92193326Sed/// ASTViewer - AST Visualization
93193326Sed
94193326Sednamespace {
95193326Sed  class ASTViewer : public ASTConsumer {
96193326Sed    ASTContext *Context;
97193326Sed  public:
98193326Sed    void Initialize(ASTContext &Context) {
99193326Sed      this->Context = &Context;
100193326Sed    }
101193326Sed
102193326Sed    virtual void HandleTopLevelDecl(DeclGroupRef D) {
103193326Sed      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
104193326Sed        HandleTopLevelSingleDecl(*I);
105193326Sed    }
106198092Srdivacky
107193326Sed    void HandleTopLevelSingleDecl(Decl *D);
108193326Sed  };
109193326Sed}
110193326Sed
111193326Sedvoid ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
112210299Sed  if (isa<FunctionDecl>(D) || isa<ObjCMethodDecl>(D)) {
113210299Sed    D->print(llvm::errs());
114210299Sed
115210299Sed    if (Stmt *Body = D->getBody()) {
116198092Srdivacky      llvm::errs() << '\n';
117198092Srdivacky      Body->viewAST();
118198092Srdivacky      llvm::errs() << '\n';
119193326Sed    }
120193326Sed  }
121193326Sed}
122193326Sed
123193326Sed
124193326SedASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); }
125193326Sed
126193326Sed//===----------------------------------------------------------------------===//
127193326Sed/// DeclContextPrinter - Decl and DeclContext Visualization
128193326Sed
129193326Sednamespace {
130193326Sed
131193326Sedclass DeclContextPrinter : public ASTConsumer {
132193326Sed  llvm::raw_ostream& Out;
133193326Sedpublic:
134193326Sed  DeclContextPrinter() : Out(llvm::errs()) {}
135193326Sed
136193326Sed  void HandleTranslationUnit(ASTContext &C) {
137193326Sed    PrintDeclContext(C.getTranslationUnitDecl(), 4);
138193326Sed  }
139193326Sed
140193326Sed  void PrintDeclContext(const DeclContext* DC, unsigned Indentation);
141193326Sed};
142193326Sed}  // end anonymous namespace
143193326Sed
144198092Srdivackyvoid DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
145193326Sed                                          unsigned Indentation) {
146193326Sed  // Print DeclContext name.
147193326Sed  switch (DC->getDeclKind()) {
148193326Sed  case Decl::TranslationUnit:
149193326Sed    Out << "[translation unit] " << DC;
150193326Sed    break;
151193326Sed  case Decl::Namespace: {
152193326Sed    Out << "[namespace] ";
153193326Sed    const NamespaceDecl* ND = cast<NamespaceDecl>(DC);
154207619Srdivacky    Out << ND;
155193326Sed    break;
156193326Sed  }
157193326Sed  case Decl::Enum: {
158193326Sed    const EnumDecl* ED = cast<EnumDecl>(DC);
159193326Sed    if (ED->isDefinition())
160193326Sed      Out << "[enum] ";
161193326Sed    else
162193326Sed      Out << "<enum> ";
163207619Srdivacky    Out << ED;
164193326Sed    break;
165193326Sed  }
166193326Sed  case Decl::Record: {
167193326Sed    const RecordDecl* RD = cast<RecordDecl>(DC);
168193326Sed    if (RD->isDefinition())
169193326Sed      Out << "[struct] ";
170193326Sed    else
171193326Sed      Out << "<struct> ";
172207619Srdivacky    Out << RD;
173193326Sed    break;
174193326Sed  }
175193326Sed  case Decl::CXXRecord: {
176193326Sed    const CXXRecordDecl* RD = cast<CXXRecordDecl>(DC);
177193326Sed    if (RD->isDefinition())
178193326Sed      Out << "[class] ";
179193326Sed    else
180193326Sed      Out << "<class> ";
181207619Srdivacky    Out << RD << ' ' << DC;
182193326Sed    break;
183193326Sed  }
184193326Sed  case Decl::ObjCMethod:
185193326Sed    Out << "[objc method]";
186193326Sed    break;
187193326Sed  case Decl::ObjCInterface:
188193326Sed    Out << "[objc interface]";
189193326Sed    break;
190193326Sed  case Decl::ObjCCategory:
191193326Sed    Out << "[objc category]";
192193326Sed    break;
193193326Sed  case Decl::ObjCProtocol:
194193326Sed    Out << "[objc protocol]";
195193326Sed    break;
196193326Sed  case Decl::ObjCImplementation:
197193326Sed    Out << "[objc implementation]";
198193326Sed    break;
199193326Sed  case Decl::ObjCCategoryImpl:
200193326Sed    Out << "[objc categoryimpl]";
201193326Sed    break;
202193326Sed  case Decl::LinkageSpec:
203193326Sed    Out << "[linkage spec]";
204193326Sed    break;
205193326Sed  case Decl::Block:
206193326Sed    Out << "[block]";
207193326Sed    break;
208193326Sed  case Decl::Function: {
209193326Sed    const FunctionDecl* FD = cast<FunctionDecl>(DC);
210193326Sed    if (FD->isThisDeclarationADefinition())
211193326Sed      Out << "[function] ";
212193326Sed    else
213193326Sed      Out << "<function> ";
214207619Srdivacky    Out << FD;
215193326Sed    // Print the parameters.
216193326Sed    Out << "(";
217193326Sed    bool PrintComma = false;
218198092Srdivacky    for (FunctionDecl::param_const_iterator I = FD->param_begin(),
219193326Sed           E = FD->param_end(); I != E; ++I) {
220193326Sed      if (PrintComma)
221193326Sed        Out << ", ";
222193326Sed      else
223193326Sed        PrintComma = true;
224207619Srdivacky      Out << *I;
225193326Sed    }
226193326Sed    Out << ")";
227193326Sed    break;
228193326Sed  }
229193326Sed  case Decl::CXXMethod: {
230193326Sed    const CXXMethodDecl* D = cast<CXXMethodDecl>(DC);
231194613Sed    if (D->isOutOfLine())
232193326Sed      Out << "[c++ method] ";
233193326Sed    else if (D->isImplicit())
234193326Sed      Out << "(c++ method) ";
235193326Sed    else
236193326Sed      Out << "<c++ method> ";
237207619Srdivacky    Out << D;
238193326Sed    // Print the parameters.
239193326Sed    Out << "(";
240193326Sed    bool PrintComma = false;
241198092Srdivacky    for (FunctionDecl::param_const_iterator I = D->param_begin(),
242193326Sed           E = D->param_end(); I != E; ++I) {
243193326Sed      if (PrintComma)
244193326Sed        Out << ", ";
245193326Sed      else
246193326Sed        PrintComma = true;
247207619Srdivacky      Out << *I;
248193326Sed    }
249193326Sed    Out << ")";
250193326Sed
251193326Sed    // Check the semantic DeclContext.
252193326Sed    const DeclContext* SemaDC = D->getDeclContext();
253193326Sed    const DeclContext* LexicalDC = D->getLexicalDeclContext();
254193326Sed    if (SemaDC != LexicalDC)
255193326Sed      Out << " [[" << SemaDC << "]]";
256193326Sed
257193326Sed    break;
258193326Sed  }
259193326Sed  case Decl::CXXConstructor: {
260193326Sed    const CXXConstructorDecl* D = cast<CXXConstructorDecl>(DC);
261194613Sed    if (D->isOutOfLine())
262193326Sed      Out << "[c++ ctor] ";
263193326Sed    else if (D->isImplicit())
264193326Sed      Out << "(c++ ctor) ";
265193326Sed    else
266193326Sed      Out << "<c++ ctor> ";
267207619Srdivacky    Out << D;
268193326Sed    // Print the parameters.
269193326Sed    Out << "(";
270193326Sed    bool PrintComma = false;
271198092Srdivacky    for (FunctionDecl::param_const_iterator I = D->param_begin(),
272193326Sed           E = D->param_end(); I != E; ++I) {
273193326Sed      if (PrintComma)
274193326Sed        Out << ", ";
275193326Sed      else
276193326Sed        PrintComma = true;
277207619Srdivacky      Out << *I;
278193326Sed    }
279193326Sed    Out << ")";
280193326Sed
281193326Sed    // Check the semantic DC.
282193326Sed    const DeclContext* SemaDC = D->getDeclContext();
283193326Sed    const DeclContext* LexicalDC = D->getLexicalDeclContext();
284193326Sed    if (SemaDC != LexicalDC)
285193326Sed      Out << " [[" << SemaDC << "]]";
286193326Sed    break;
287193326Sed  }
288193326Sed  case Decl::CXXDestructor: {
289193326Sed    const CXXDestructorDecl* D = cast<CXXDestructorDecl>(DC);
290194613Sed    if (D->isOutOfLine())
291193326Sed      Out << "[c++ dtor] ";
292193326Sed    else if (D->isImplicit())
293193326Sed      Out << "(c++ dtor) ";
294193326Sed    else
295193326Sed      Out << "<c++ dtor> ";
296207619Srdivacky    Out << D;
297193326Sed    // Check the semantic DC.
298193326Sed    const DeclContext* SemaDC = D->getDeclContext();
299193326Sed    const DeclContext* LexicalDC = D->getLexicalDeclContext();
300193326Sed    if (SemaDC != LexicalDC)
301193326Sed      Out << " [[" << SemaDC << "]]";
302193326Sed    break;
303193326Sed  }
304193326Sed  case Decl::CXXConversion: {
305193326Sed    const CXXConversionDecl* D = cast<CXXConversionDecl>(DC);
306194613Sed    if (D->isOutOfLine())
307193326Sed      Out << "[c++ conversion] ";
308193326Sed    else if (D->isImplicit())
309193326Sed      Out << "(c++ conversion) ";
310193326Sed    else
311193326Sed      Out << "<c++ conversion> ";
312207619Srdivacky    Out << D;
313193326Sed    // Check the semantic DC.
314193326Sed    const DeclContext* SemaDC = D->getDeclContext();
315193326Sed    const DeclContext* LexicalDC = D->getLexicalDeclContext();
316193326Sed    if (SemaDC != LexicalDC)
317193326Sed      Out << " [[" << SemaDC << "]]";
318193326Sed    break;
319193326Sed  }
320193326Sed
321193326Sed  default:
322193326Sed    assert(0 && "a decl that inherits DeclContext isn't handled");
323193326Sed  }
324193326Sed
325193326Sed  Out << "\n";
326193326Sed
327193326Sed  // Print decls in the DeclContext.
328195341Sed  for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
329193326Sed       I != E; ++I) {
330193326Sed    for (unsigned i = 0; i < Indentation; ++i)
331193326Sed      Out << "  ";
332193326Sed
333193326Sed    Decl::Kind DK = I->getKind();
334193326Sed    switch (DK) {
335193326Sed    case Decl::Namespace:
336193326Sed    case Decl::Enum:
337193326Sed    case Decl::Record:
338193326Sed    case Decl::CXXRecord:
339193326Sed    case Decl::ObjCMethod:
340193326Sed    case Decl::ObjCInterface:
341198092Srdivacky    case Decl::ObjCCategory:
342193326Sed    case Decl::ObjCProtocol:
343193326Sed    case Decl::ObjCImplementation:
344193326Sed    case Decl::ObjCCategoryImpl:
345193326Sed    case Decl::LinkageSpec:
346193326Sed    case Decl::Block:
347193326Sed    case Decl::Function:
348193326Sed    case Decl::CXXMethod:
349193326Sed    case Decl::CXXConstructor:
350193326Sed    case Decl::CXXDestructor:
351193326Sed    case Decl::CXXConversion:
352193326Sed    {
353193326Sed      DeclContext* DC = cast<DeclContext>(*I);
354193326Sed      PrintDeclContext(DC, Indentation+2);
355193326Sed      break;
356193326Sed    }
357218893Sdim    case Decl::IndirectField: {
358218893Sdim      IndirectFieldDecl* IFD = cast<IndirectFieldDecl>(*I);
359218893Sdim      Out << "<IndirectField> " << IFD << '\n';
360218893Sdim      break;
361218893Sdim    }
362218893Sdim    case Decl::Label: {
363218893Sdim      LabelDecl *LD = cast<LabelDecl>(*I);
364218893Sdim      Out << "<Label> " << LD << '\n';
365218893Sdim      break;
366218893Sdim    }
367193326Sed    case Decl::Field: {
368218893Sdim      FieldDecl *FD = cast<FieldDecl>(*I);
369207619Srdivacky      Out << "<field> " << FD << '\n';
370193326Sed      break;
371193326Sed    }
372193326Sed    case Decl::Typedef: {
373193326Sed      TypedefDecl* TD = cast<TypedefDecl>(*I);
374207619Srdivacky      Out << "<typedef> " << TD << '\n';
375193326Sed      break;
376193326Sed    }
377193326Sed    case Decl::EnumConstant: {
378193326Sed      EnumConstantDecl* ECD = cast<EnumConstantDecl>(*I);
379207619Srdivacky      Out << "<enum constant> " << ECD << '\n';
380193326Sed      break;
381193326Sed    }
382193326Sed    case Decl::Var: {
383193326Sed      VarDecl* VD = cast<VarDecl>(*I);
384207619Srdivacky      Out << "<var> " << VD << '\n';
385193326Sed      break;
386193326Sed    }
387193326Sed    case Decl::ImplicitParam: {
388193326Sed      ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(*I);
389207619Srdivacky      Out << "<implicit parameter> " << IPD << '\n';
390193326Sed      break;
391193326Sed    }
392193326Sed    case Decl::ParmVar: {
393193326Sed      ParmVarDecl* PVD = cast<ParmVarDecl>(*I);
394207619Srdivacky      Out << "<parameter> " << PVD << '\n';
395193326Sed      break;
396193326Sed    }
397193326Sed    case Decl::ObjCProperty: {
398193326Sed      ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(*I);
399207619Srdivacky      Out << "<objc property> " << OPD << '\n';
400193326Sed      break;
401193326Sed    }
402200583Srdivacky    case Decl::FunctionTemplate: {
403200583Srdivacky      FunctionTemplateDecl* FTD = cast<FunctionTemplateDecl>(*I);
404207619Srdivacky      Out << "<function template> " << FTD << '\n';
405200583Srdivacky      break;
406200583Srdivacky    }
407202379Srdivacky    case Decl::FileScopeAsm: {
408202379Srdivacky      Out << "<file-scope asm>\n";
409202379Srdivacky      break;
410202379Srdivacky    }
411202379Srdivacky    case Decl::UsingDirective: {
412202379Srdivacky      Out << "<using directive>\n";
413202379Srdivacky      break;
414202379Srdivacky    }
415202379Srdivacky    case Decl::NamespaceAlias: {
416202379Srdivacky      NamespaceAliasDecl* NAD = cast<NamespaceAliasDecl>(*I);
417207619Srdivacky      Out << "<namespace alias> " << NAD << '\n';
418202379Srdivacky      break;
419202379Srdivacky    }
420202879Srdivacky    case Decl::ClassTemplate: {
421202879Srdivacky      ClassTemplateDecl *CTD = cast<ClassTemplateDecl>(*I);
422207619Srdivacky      Out << "<class template> " << CTD << '\n';
423202879Srdivacky      break;
424202879Srdivacky    }
425193326Sed    default:
426207619Srdivacky      Out << "DeclKind: " << DK << '"' << *I << "\"\n";
427193326Sed      assert(0 && "decl unhandled");
428193326Sed    }
429193326Sed  }
430193326Sed}
431198092SrdivackyASTConsumer *clang::CreateDeclContextPrinter() {
432198092Srdivacky  return new DeclContextPrinter();
433193326Sed}
434193326Sed
435193326Sed//===----------------------------------------------------------------------===//
436218893Sdim/// ASTDumperXML - In-depth XML dumping.
437193326Sed
438193326Sednamespace {
439218893Sdimclass ASTDumpXML : public ASTConsumer {
440218893Sdim  llvm::raw_ostream &OS;
441218893Sdim
442193326Sedpublic:
443218893Sdim  ASTDumpXML(llvm::raw_ostream &OS) : OS(OS) {}
444198092Srdivacky
445193326Sed  void HandleTranslationUnit(ASTContext &C) {
446218893Sdim    C.getTranslationUnitDecl()->dumpXML(OS);
447218893Sdim  }
448198092Srdivacky};
449193326Sed}
450193326Sed
451218893SdimASTConsumer *clang::CreateASTDumperXML(llvm::raw_ostream &OS) {
452218893Sdim  return new ASTDumpXML(OS);
453193326Sed}
454