ASTConsumers.cpp revision 195341
1221828Sgrehan//===--- ASTConsumers.cpp - ASTConsumer implementations -------------------===//
2221828Sgrehan//
3221828Sgrehan//                     The LLVM Compiler Infrastructure
4221828Sgrehan//
5221828Sgrehan// This file is distributed under the University of Illinois Open Source
6221828Sgrehan// License. See LICENSE.TXT for details.
7221828Sgrehan//
8221828Sgrehan//===----------------------------------------------------------------------===//
9221828Sgrehan//
10221828Sgrehan// AST Consumer Implementations.
11221828Sgrehan//
12221828Sgrehan//===----------------------------------------------------------------------===//
13221828Sgrehan
14221828Sgrehan#include "clang/Frontend/ASTConsumers.h"
15221828Sgrehan#include "clang/Frontend/DocumentXML.h"
16221828Sgrehan#include "clang/Frontend/PathDiagnosticClients.h"
17221828Sgrehan#include "clang/Basic/Diagnostic.h"
18221828Sgrehan#include "clang/Basic/SourceManager.h"
19221828Sgrehan#include "clang/Basic/FileManager.h"
20221828Sgrehan#include "clang/AST/AST.h"
21221828Sgrehan#include "clang/AST/ASTConsumer.h"
22221828Sgrehan#include "clang/AST/ASTContext.h"
23221828Sgrehan#include "clang/AST/PrettyPrinter.h"
24221828Sgrehan#include "clang/CodeGen/ModuleBuilder.h"
25221828Sgrehan#include "llvm/Module.h"
26221828Sgrehan#include "llvm/Support/Streams.h"
27221828Sgrehan#include "llvm/Support/Timer.h"
28221828Sgrehan#include "llvm/Support/raw_ostream.h"
29221828Sgrehan#include "llvm/System/Path.h"
30221828Sgrehanusing namespace clang;
31221828Sgrehan
32221828Sgrehan//===----------------------------------------------------------------------===//
33234695Sgrehan/// ASTPrinter - Pretty-printer and dumper of ASTs
34221828Sgrehan
35221828Sgrehannamespace {
36221828Sgrehan  class ASTPrinter : public ASTConsumer {
37221828Sgrehan    llvm::raw_ostream &Out;
38221828Sgrehan    bool Dump;
39221828Sgrehan
40221828Sgrehan  public:
41221828Sgrehan    ASTPrinter(llvm::raw_ostream* o = NULL, bool Dump = false)
42256072Sneel      : Out(o? *o : llvm::errs()), Dump(Dump) { }
43221828Sgrehan
44221828Sgrehan    virtual void HandleTranslationUnit(ASTContext &Context) {
45221828Sgrehan      PrintingPolicy Policy = Context.PrintingPolicy;
46221828Sgrehan      Policy.Dump = Dump;
47221828Sgrehan      Context.getTranslationUnitDecl()->print(Out, Policy);
48256072Sneel    }
49256072Sneel  };
50256072Sneel} // end anonymous namespace
51256072Sneel
52256072SneelASTConsumer *clang::CreateASTPrinter(llvm::raw_ostream* out) {
53256072Sneel  return new ASTPrinter(out);
54221828Sgrehan}
55261275Sjhb
56221828Sgrehan//===----------------------------------------------------------------------===//
57221828Sgrehan/// ASTPrinterXML - XML-printer of ASTs
58241489Sneel
59262350Sjhbnamespace {
60221914Sjhb  class ASTPrinterXML : public ASTConsumer {
61256072Sneel    DocumentXML         Doc;
62221828Sgrehan
63221828Sgrehan  public:
64261088Sjhb    ASTPrinterXML(llvm::raw_ostream& o) : Doc("CLANG_XML", o) {}
65268976Sjhb
66261088Sjhb    void Initialize(ASTContext &Context) {
67268976Sjhb      Doc.initialize(Context);
68256072Sneel    }
69242275Sneel
70221828Sgrehan    virtual void HandleTranslationUnit(ASTContext &Ctx) {
71221828Sgrehan      Doc.addSubNode("TranslationUnit");
72268891Sjhb      for (DeclContext::decl_iterator
73268891Sjhb             D = Ctx.getTranslationUnitDecl()->decls_begin(),
74261088Sjhb             DEnd = Ctx.getTranslationUnitDecl()->decls_end();
75261088Sjhb           D != DEnd;
76221828Sgrehan           ++D)
77276429Sneel      {
78284894Sneel        Doc.PrintDecl(*D);
79221828Sgrehan      }
80221828Sgrehan      Doc.toParent();
81242065Sneel      Doc.finalize();
82221828Sgrehan    }
83221828Sgrehan  };
84221828Sgrehan} // end anonymous namespace
85221828Sgrehan
86221828Sgrehan
87221828SgrehanASTConsumer *clang::CreateASTPrinterXML(llvm::raw_ostream* out) {
88270071Sgrehan  return new ASTPrinterXML(out ? *out : llvm::outs());
89270071Sgrehan}
90270071Sgrehan
91270071SgrehanASTConsumer *clang::CreateASTDumper() {
92270071Sgrehan  return new ASTPrinter(0, true);
93270071Sgrehan}
94270071Sgrehan
95221828Sgrehan//===----------------------------------------------------------------------===//
96270071Sgrehan/// ASTViewer - AST Visualization
97270071Sgrehan
98270071Sgrehannamespace {
99284900Sneel  class ASTViewer : public ASTConsumer {
100270071Sgrehan    ASTContext *Context;
101270071Sgrehan  public:
102270159Sgrehan    void Initialize(ASTContext &Context) {
103270071Sgrehan      this->Context = &Context;
104270071Sgrehan    }
105270071Sgrehan
106284894Sneel    virtual void HandleTopLevelDecl(DeclGroupRef D) {
107284894Sneel      for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
108284894Sneel        HandleTopLevelSingleDecl(*I);
109270071Sgrehan    }
110270071Sgrehan
111270071Sgrehan    void HandleTopLevelSingleDecl(Decl *D);
112270071Sgrehan  };
113284894Sneel}
114221828Sgrehan
115221828Sgrehanvoid ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
116270071Sgrehan  if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
117242065Sneel    FD->print(llvm::errs());
118242065Sneel
119242065Sneel    if (FD->getBodyIfAvailable()) {
120256072Sneel      llvm::cerr << '\n';
121241489Sneel      FD->getBodyIfAvailable()->viewAST();
122256072Sneel      llvm::cerr << '\n';
123295124Sgrehan    }
124295124Sgrehan    return;
125295124Sgrehan  }
126295124Sgrehan
127295124Sgrehan  if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
128295124Sgrehan    MD->print(llvm::errs());
129295124Sgrehan
130256072Sneel    if (MD->getBody()) {
131256072Sneel      llvm::cerr << '\n';
132295124Sgrehan      MD->getBody()->viewAST();
133295124Sgrehan      llvm::cerr << '\n';
134295124Sgrehan    }
135295124Sgrehan  }
136256072Sneel}
137295124Sgrehan
138221828Sgrehan
139270071SgrehanASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); }
140270071Sgrehan
141270071Sgrehan//===----------------------------------------------------------------------===//
142270071Sgrehan/// DeclContextPrinter - Decl and DeclContext Visualization
143270071Sgrehan
144270071Sgrehannamespace {
145221828Sgrehan
146270071Sgrehanclass DeclContextPrinter : public ASTConsumer {
147270071Sgrehan  llvm::raw_ostream& Out;
148270071Sgrehanpublic:
149270071Sgrehan  DeclContextPrinter() : Out(llvm::errs()) {}
150270071Sgrehan
151270071Sgrehan  void HandleTranslationUnit(ASTContext &C) {
152276429Sneel    PrintDeclContext(C.getTranslationUnitDecl(), 4);
153284894Sneel  }
154270071Sgrehan
155270071Sgrehan  void PrintDeclContext(const DeclContext* DC, unsigned Indentation);
156270071Sgrehan};
157270071Sgrehan}  // end anonymous namespace
158270071Sgrehan
159270071Sgrehanvoid DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
160270071Sgrehan                                          unsigned Indentation) {
161270071Sgrehan  // Print DeclContext name.
162270071Sgrehan  switch (DC->getDeclKind()) {
163295124Sgrehan  case Decl::TranslationUnit:
164295124Sgrehan    Out << "[translation unit] " << DC;
165270071Sgrehan    break;
166270071Sgrehan  case Decl::Namespace: {
167270071Sgrehan    Out << "[namespace] ";
168221828Sgrehan    const NamespaceDecl* ND = cast<NamespaceDecl>(DC);
169221828Sgrehan    Out << ND->getNameAsString();
170249396Sneel    break;
171249396Sneel  }
172221828Sgrehan  case Decl::Enum: {
173266339Sjhb    const EnumDecl* ED = cast<EnumDecl>(DC);
174221828Sgrehan    if (ED->isDefinition())
175261275Sjhb      Out << "[enum] ";
176221828Sgrehan    else
177256072Sneel      Out << "<enum> ";
178284900Sneel    Out << ED->getNameAsString();
179284900Sneel    break;
180221828Sgrehan  }
181256072Sneel  case Decl::Record: {
182256072Sneel    const RecordDecl* RD = cast<RecordDecl>(DC);
183256072Sneel    if (RD->isDefinition())
184256072Sneel      Out << "[struct] ";
185221828Sgrehan    else
186221828Sgrehan      Out << "<struct> ";
187221828Sgrehan    Out << RD->getNameAsString();
188221828Sgrehan    break;
189221828Sgrehan  }
190221828Sgrehan  case Decl::CXXRecord: {
191221828Sgrehan    const CXXRecordDecl* RD = cast<CXXRecordDecl>(DC);
192221828Sgrehan    if (RD->isDefinition())
193221828Sgrehan      Out << "[class] ";
194221828Sgrehan    else
195221828Sgrehan      Out << "<class> ";
196221828Sgrehan    Out << RD->getNameAsString() << " " << DC;
197266339Sjhb    break;
198266339Sjhb  }
199266339Sjhb  case Decl::ObjCMethod:
200266339Sjhb    Out << "[objc method]";
201221828Sgrehan    break;
202245021Sneel  case Decl::ObjCInterface:
203245021Sneel    Out << "[objc interface]";
204221828Sgrehan    break;
205221828Sgrehan  case Decl::ObjCCategory:
206221828Sgrehan    Out << "[objc category]";
207221828Sgrehan    break;
208248389Sneel  case Decl::ObjCProtocol:
209221828Sgrehan    Out << "[objc protocol]";
210266339Sjhb    break;
211266339Sjhb  case Decl::ObjCImplementation:
212268935Sjhb    Out << "[objc implementation]";
213268935Sjhb    break;
214268935Sjhb  case Decl::ObjCCategoryImpl:
215268935Sjhb    Out << "[objc categoryimpl]";
216268935Sjhb    break;
217268935Sjhb  case Decl::LinkageSpec:
218268935Sjhb    Out << "[linkage spec]";
219268935Sjhb    break;
220268935Sjhb  case Decl::Block:
221268935Sjhb    Out << "[block]";
222266339Sjhb    break;
223266339Sjhb  case Decl::Function: {
224266339Sjhb    const FunctionDecl* FD = cast<FunctionDecl>(DC);
225266339Sjhb    if (FD->isThisDeclarationADefinition())
226276403Sneel      Out << "[function] ";
227276403Sneel    else
228276403Sneel      Out << "<function> ";
229276403Sneel    Out << FD->getNameAsString();
230276403Sneel    // Print the parameters.
231284899Sneel    Out << "(";
232284899Sneel    bool PrintComma = false;
233284899Sneel    for (FunctionDecl::param_const_iterator I = FD->param_begin(),
234284899Sneel           E = FD->param_end(); I != E; ++I) {
235284899Sneel      if (PrintComma)
236295124Sgrehan        Out << ", ";
237295124Sgrehan      else
238284900Sneel        PrintComma = true;
239284900Sneel      Out << (*I)->getNameAsString();
240284900Sneel    }
241284900Sneel    Out << ")";
242284900Sneel    break;
243284900Sneel  }
244284900Sneel  case Decl::CXXMethod: {
245284900Sneel    const CXXMethodDecl* D = cast<CXXMethodDecl>(DC);
246284900Sneel    if (D->isOutOfLine())
247284900Sneel      Out << "[c++ method] ";
248284900Sneel    else if (D->isImplicit())
249284900Sneel      Out << "(c++ method) ";
250284900Sneel    else
251284900Sneel      Out << "<c++ method> ";
252284900Sneel    Out << D->getNameAsString();
253284900Sneel    // Print the parameters.
254284900Sneel    Out << "(";
255284900Sneel    bool PrintComma = false;
256284900Sneel    for (FunctionDecl::param_const_iterator I = D->param_begin(),
257284900Sneel           E = D->param_end(); I != E; ++I) {
258284900Sneel      if (PrintComma)
259284900Sneel        Out << ", ";
260221828Sgrehan      else
261270071Sgrehan        PrintComma = true;
262221828Sgrehan      Out << (*I)->getNameAsString();
263266339Sjhb    }
264266339Sjhb    Out << ")";
265266339Sjhb
266270071Sgrehan    // Check the semantic DeclContext.
267270071Sgrehan    const DeclContext* SemaDC = D->getDeclContext();
268270071Sgrehan    const DeclContext* LexicalDC = D->getLexicalDeclContext();
269270071Sgrehan    if (SemaDC != LexicalDC)
270221828Sgrehan      Out << " [[" << SemaDC << "]]";
271221828Sgrehan
272221828Sgrehan    break;
273270071Sgrehan  }
274221828Sgrehan  case Decl::CXXConstructor: {
275221828Sgrehan    const CXXConstructorDecl* D = cast<CXXConstructorDecl>(DC);
276270071Sgrehan    if (D->isOutOfLine())
277270071Sgrehan      Out << "[c++ ctor] ";
278270071Sgrehan    else if (D->isImplicit())
279270071Sgrehan      Out << "(c++ ctor) ";
280221828Sgrehan    else
281221828Sgrehan      Out << "<c++ ctor> ";
282270071Sgrehan    Out << D->getNameAsString();
283270071Sgrehan    // Print the parameters.
284270071Sgrehan    Out << "(";
285270071Sgrehan    bool PrintComma = false;
286270071Sgrehan    for (FunctionDecl::param_const_iterator I = D->param_begin(),
287270071Sgrehan           E = D->param_end(); I != E; ++I) {
288270071Sgrehan      if (PrintComma)
289270071Sgrehan        Out << ", ";
290270071Sgrehan      else
291270071Sgrehan        PrintComma = true;
292266339Sjhb      Out << (*I)->getNameAsString();
293267447Sjhb    }
294284900Sneel    Out << ")";
295270159Sgrehan
296270071Sgrehan    // Check the semantic DC.
297270071Sgrehan    const DeclContext* SemaDC = D->getDeclContext();
298270071Sgrehan    const DeclContext* LexicalDC = D->getLexicalDeclContext();
299267427Sjhb    if (SemaDC != LexicalDC)
300234695Sgrehan      Out << " [[" << SemaDC << "]]";
301270071Sgrehan    break;
302221828Sgrehan  }
303221828Sgrehan  case Decl::CXXDestructor: {
304276403Sneel    const CXXDestructorDecl* D = cast<CXXDestructorDecl>(DC);
305276403Sneel    if (D->isOutOfLine())
306276403Sneel      Out << "[c++ dtor] ";
307276403Sneel    else if (D->isImplicit())
308276403Sneel      Out << "(c++ dtor) ";
309276403Sneel    else
310276403Sneel      Out << "<c++ dtor> ";
311240894Sneel    Out << D->getNameAsString();
312240894Sneel    // Check the semantic DC.
313240894Sneel    const DeclContext* SemaDC = D->getDeclContext();
314240894Sneel    const DeclContext* LexicalDC = D->getLexicalDeclContext();
315240894Sneel    if (SemaDC != LexicalDC)
316240894Sneel      Out << " [[" << SemaDC << "]]";
317240894Sneel    break;
318240894Sneel  }
319240894Sneel  case Decl::CXXConversion: {
320240894Sneel    const CXXConversionDecl* D = cast<CXXConversionDecl>(DC);
321240894Sneel    if (D->isOutOfLine())
322240894Sneel      Out << "[c++ conversion] ";
323240894Sneel    else if (D->isImplicit())
324261275Sjhb      Out << "(c++ conversion) ";
325261275Sjhb    else
326261275Sjhb      Out << "<c++ conversion> ";
327261275Sjhb    Out << D->getNameAsString();
328261275Sjhb    // Check the semantic DC.
329261275Sjhb    const DeclContext* SemaDC = D->getDeclContext();
330221828Sgrehan    const DeclContext* LexicalDC = D->getLexicalDeclContext();
331221828Sgrehan    if (SemaDC != LexicalDC)
332221828Sgrehan      Out << " [[" << SemaDC << "]]";
333221828Sgrehan    break;
334221828Sgrehan  }
335242275Sneel
336221828Sgrehan  default:
337266339Sjhb    assert(0 && "a decl that inherits DeclContext isn't handled");
338266339Sjhb  }
339266339Sjhb
340266339Sjhb  Out << "\n";
341221828Sgrehan
342221828Sgrehan  // Print decls in the DeclContext.
343221828Sgrehan  for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
344221828Sgrehan       I != E; ++I) {
345221828Sgrehan    for (unsigned i = 0; i < Indentation; ++i)
346221828Sgrehan      Out << "  ";
347221828Sgrehan
348221828Sgrehan    Decl::Kind DK = I->getKind();
349221828Sgrehan    switch (DK) {
350221828Sgrehan    case Decl::Namespace:
351221828Sgrehan    case Decl::Enum:
352261275Sjhb    case Decl::Record:
353221828Sgrehan    case Decl::CXXRecord:
354266339Sjhb    case Decl::ObjCMethod:
355221828Sgrehan    case Decl::ObjCInterface:
356221828Sgrehan    case Decl::ObjCCategory:
357221828Sgrehan    case Decl::ObjCProtocol:
358221828Sgrehan    case Decl::ObjCImplementation:
359221828Sgrehan    case Decl::ObjCCategoryImpl:
360221828Sgrehan    case Decl::LinkageSpec:
361221828Sgrehan    case Decl::Block:
362221828Sgrehan    case Decl::Function:
363221828Sgrehan    case Decl::CXXMethod:
364221828Sgrehan    case Decl::CXXConstructor:
365284899Sneel    case Decl::CXXDestructor:
366267070Sjhb    case Decl::CXXConversion:
367221828Sgrehan    {
368249396Sneel      DeclContext* DC = cast<DeclContext>(*I);
369249396Sneel      PrintDeclContext(DC, Indentation+2);
370221828Sgrehan      break;
371221828Sgrehan    }
372241454Sneel    case Decl::Field: {
373241454Sneel      FieldDecl* FD = cast<FieldDecl>(*I);
374261275Sjhb      Out << "<field> " << FD->getNameAsString() << "\n";
375241454Sneel      break;
376266339Sjhb    }
377266339Sjhb    case Decl::Typedef: {
378241454Sneel      TypedefDecl* TD = cast<TypedefDecl>(*I);
379253854Sgrehan      Out << "<typedef> " << TD->getNameAsString() << "\n";
380253854Sgrehan      break;
381253854Sgrehan    }
382253854Sgrehan    case Decl::EnumConstant: {
383253854Sgrehan      EnumConstantDecl* ECD = cast<EnumConstantDecl>(*I);
384253854Sgrehan      Out << "<enum constant> " << ECD->getNameAsString() << "\n";
385241454Sneel      break;
386221828Sgrehan    }
387221828Sgrehan    case Decl::Var: {
388221828Sgrehan      VarDecl* VD = cast<VarDecl>(*I);
389221828Sgrehan      Out << "<var> " << VD->getNameAsString() << "\n";
390221828Sgrehan      break;
391221828Sgrehan    }
392221828Sgrehan    case Decl::ImplicitParam: {
393221828Sgrehan      ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(*I);
394221828Sgrehan      Out << "<implicit parameter> " << IPD->getNameAsString() << "\n";
395221828Sgrehan      break;
396221828Sgrehan    }
397221828Sgrehan    case Decl::ParmVar: {
398221828Sgrehan      ParmVarDecl* PVD = cast<ParmVarDecl>(*I);
399221828Sgrehan      Out << "<parameter> " << PVD->getNameAsString() << "\n";
400221828Sgrehan      break;
401245704Sneel    }
402245704Sneel    case Decl::OriginalParmVar: {
403245704Sneel      OriginalParmVarDecl* OPVD = cast<OriginalParmVarDecl>(*I);
404245704Sneel      Out << "<original parameter> " << OPVD->getNameAsString() << "\n";
405245704Sneel      break;
406245704Sneel    }
407245704Sneel    case Decl::ObjCProperty: {
408221828Sgrehan      ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(*I);
409245704Sneel      Out << "<objc property> " << OPD->getNameAsString() << "\n";
410221828Sgrehan      break;
411221828Sgrehan    }
412270071Sgrehan    default:
413270071Sgrehan      fprintf(stderr, "DeclKind: %d \"%s\"\n", DK, I->getDeclKindName());
414270071Sgrehan      assert(0 && "decl unhandled");
415270071Sgrehan    }
416270071Sgrehan  }
417270071Sgrehan}
418270071SgrehanASTConsumer *clang::CreateDeclContextPrinter() {
419270071Sgrehan  return new DeclContextPrinter();
420270071Sgrehan}
421270071Sgrehan
422270071Sgrehan//===----------------------------------------------------------------------===//
423276429Sneel/// InheritanceViewer - C++ Inheritance Visualization
424284894Sneel
425284894Sneelnamespace {
426270071Sgrehanclass InheritanceViewer : public ASTConsumer {
427270071Sgrehan  const std::string clsname;
428270071Sgrehanpublic:
429270071Sgrehan  InheritanceViewer(const std::string& cname) : clsname(cname) {}
430270071Sgrehan
431270071Sgrehan  void HandleTranslationUnit(ASTContext &C) {
432270071Sgrehan    for (ASTContext::type_iterator I=C.types_begin(),E=C.types_end(); I!=E; ++I)
433270071Sgrehan      if (RecordType *T = dyn_cast<RecordType>(*I)) {
434270071Sgrehan        if (CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(T->getDecl())) {
435270071Sgrehan          // FIXME: This lookup needs to be generalized to handle namespaces and
436249396Sneel          // (when we support them) templates.
437249396Sneel          if (D->getNameAsString() == clsname) {
438221828Sgrehan            D->viewInheritance(C);
439221828Sgrehan          }
440256072Sneel        }
441221828Sgrehan      }
442249396Sneel  }
443249396Sneel};
444249396Sneel}
445249396Sneel
446249396SneelASTConsumer *clang::CreateInheritanceViewer(const std::string& clsname) {
447249396Sneel  return new InheritanceViewer(clsname);
448249396Sneel}
449221828Sgrehan