]> CyberLeo.Net >> Repos - FreeBSD/FreeBSD.git/blob - lib/Frontend/ASTConsumers.cpp
Update clang to r93512.
[FreeBSD/FreeBSD.git] / 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/Frontend/DocumentXML.h"
16 #include "clang/Frontend/PathDiagnosticClients.h"
17 #include "clang/Basic/Diagnostic.h"
18 #include "clang/Basic/SourceManager.h"
19 #include "clang/Basic/FileManager.h"
20 #include "clang/AST/AST.h"
21 #include "clang/AST/ASTConsumer.h"
22 #include "clang/AST/ASTContext.h"
23 #include "clang/AST/RecordLayout.h"
24 #include "clang/AST/PrettyPrinter.h"
25 #include "clang/CodeGen/ModuleBuilder.h"
26 #include "llvm/Module.h"
27 #include "llvm/Support/Format.h"
28 #include "llvm/Support/Timer.h"
29 #include "llvm/Support/raw_ostream.h"
30 #include "llvm/System/Path.h"
31 using namespace clang;
32
33 //===----------------------------------------------------------------------===//
34 /// ASTPrinter - Pretty-printer and dumper of ASTs
35
36 namespace {
37   class ASTPrinter : public ASTConsumer {
38     llvm::raw_ostream &Out;
39     bool Dump;
40
41   public:
42     ASTPrinter(llvm::raw_ostream* o = NULL, bool Dump = false)
43       : Out(o? *o : llvm::errs()), Dump(Dump) { }
44
45     virtual void HandleTranslationUnit(ASTContext &Context) {
46       PrintingPolicy Policy = Context.PrintingPolicy;
47       Policy.Dump = Dump;
48       Context.getTranslationUnitDecl()->print(Out, Policy);
49     }
50   };
51 } // end anonymous namespace
52
53 ASTConsumer *clang::CreateASTPrinter(llvm::raw_ostream* out) {
54   return new ASTPrinter(out);
55 }
56
57 //===----------------------------------------------------------------------===//
58 /// ASTPrinterXML - XML-printer of ASTs
59
60 namespace {
61   class ASTPrinterXML : public ASTConsumer {
62     DocumentXML         Doc;
63
64   public:
65     ASTPrinterXML(llvm::raw_ostream& o) : Doc("CLANG_XML", o) {}
66
67     void Initialize(ASTContext &Context) {
68       Doc.initialize(Context);
69     }
70
71     virtual void HandleTranslationUnit(ASTContext &Ctx) {
72       Doc.addSubNode("TranslationUnit");
73       for (DeclContext::decl_iterator
74              D = Ctx.getTranslationUnitDecl()->decls_begin(),
75              DEnd = Ctx.getTranslationUnitDecl()->decls_end();
76            D != DEnd;
77            ++D)
78         Doc.PrintDecl(*D);
79       Doc.toParent();
80       Doc.finalize();
81     }
82   };
83 } // end anonymous namespace
84
85
86 ASTConsumer *clang::CreateASTPrinterXML(llvm::raw_ostream* out) {
87   return new ASTPrinterXML(out ? *out : llvm::outs());
88 }
89
90 ASTConsumer *clang::CreateASTDumper() {
91   return new ASTPrinter(0, true);
92 }
93
94 //===----------------------------------------------------------------------===//
95 /// ASTViewer - AST Visualization
96
97 namespace {
98   class ASTViewer : public ASTConsumer {
99     ASTContext *Context;
100   public:
101     void Initialize(ASTContext &Context) {
102       this->Context = &Context;
103     }
104
105     virtual void HandleTopLevelDecl(DeclGroupRef D) {
106       for (DeclGroupRef::iterator I = D.begin(), E = D.end(); I != E; ++I)
107         HandleTopLevelSingleDecl(*I);
108     }
109
110     void HandleTopLevelSingleDecl(Decl *D);
111   };
112 }
113
114 void ASTViewer::HandleTopLevelSingleDecl(Decl *D) {
115   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
116     FD->print(llvm::errs());
117
118     if (Stmt *Body = FD->getBody()) {
119       llvm::errs() << '\n';
120       Body->viewAST();
121       llvm::errs() << '\n';
122     }
123     return;
124   }
125
126   if (ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
127     MD->print(llvm::errs());
128
129     if (MD->getBody()) {
130       llvm::errs() << '\n';
131       MD->getBody()->viewAST();
132       llvm::errs() << '\n';
133     }
134   }
135 }
136
137
138 ASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); }
139
140 //===----------------------------------------------------------------------===//
141 /// DeclContextPrinter - Decl and DeclContext Visualization
142
143 namespace {
144
145 class DeclContextPrinter : public ASTConsumer {
146   llvm::raw_ostream& Out;
147 public:
148   DeclContextPrinter() : Out(llvm::errs()) {}
149
150   void HandleTranslationUnit(ASTContext &C) {
151     PrintDeclContext(C.getTranslationUnitDecl(), 4);
152   }
153
154   void PrintDeclContext(const DeclContext* DC, unsigned Indentation);
155 };
156 }  // end anonymous namespace
157
158 void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
159                                           unsigned Indentation) {
160   // Print DeclContext name.
161   switch (DC->getDeclKind()) {
162   case Decl::TranslationUnit:
163     Out << "[translation unit] " << DC;
164     break;
165   case Decl::Namespace: {
166     Out << "[namespace] ";
167     const NamespaceDecl* ND = cast<NamespaceDecl>(DC);
168     Out << ND->getNameAsString();
169     break;
170   }
171   case Decl::Enum: {
172     const EnumDecl* ED = cast<EnumDecl>(DC);
173     if (ED->isDefinition())
174       Out << "[enum] ";
175     else
176       Out << "<enum> ";
177     Out << ED->getNameAsString();
178     break;
179   }
180   case Decl::Record: {
181     const RecordDecl* RD = cast<RecordDecl>(DC);
182     if (RD->isDefinition())
183       Out << "[struct] ";
184     else
185       Out << "<struct> ";
186     Out << RD->getNameAsString();
187     break;
188   }
189   case Decl::CXXRecord: {
190     const CXXRecordDecl* RD = cast<CXXRecordDecl>(DC);
191     if (RD->isDefinition())
192       Out << "[class] ";
193     else
194       Out << "<class> ";
195     Out << RD->getNameAsString() << " " << DC;
196     break;
197   }
198   case Decl::ObjCMethod:
199     Out << "[objc method]";
200     break;
201   case Decl::ObjCInterface:
202     Out << "[objc interface]";
203     break;
204   case Decl::ObjCCategory:
205     Out << "[objc category]";
206     break;
207   case Decl::ObjCProtocol:
208     Out << "[objc protocol]";
209     break;
210   case Decl::ObjCImplementation:
211     Out << "[objc implementation]";
212     break;
213   case Decl::ObjCCategoryImpl:
214     Out << "[objc categoryimpl]";
215     break;
216   case Decl::LinkageSpec:
217     Out << "[linkage spec]";
218     break;
219   case Decl::Block:
220     Out << "[block]";
221     break;
222   case Decl::Function: {
223     const FunctionDecl* FD = cast<FunctionDecl>(DC);
224     if (FD->isThisDeclarationADefinition())
225       Out << "[function] ";
226     else
227       Out << "<function> ";
228     Out << FD->getNameAsString();
229     // Print the parameters.
230     Out << "(";
231     bool PrintComma = false;
232     for (FunctionDecl::param_const_iterator I = FD->param_begin(),
233            E = FD->param_end(); I != E; ++I) {
234       if (PrintComma)
235         Out << ", ";
236       else
237         PrintComma = true;
238       Out << (*I)->getNameAsString();
239     }
240     Out << ")";
241     break;
242   }
243   case Decl::CXXMethod: {
244     const CXXMethodDecl* D = cast<CXXMethodDecl>(DC);
245     if (D->isOutOfLine())
246       Out << "[c++ method] ";
247     else if (D->isImplicit())
248       Out << "(c++ method) ";
249     else
250       Out << "<c++ method> ";
251     Out << D->getNameAsString();
252     // Print the parameters.
253     Out << "(";
254     bool PrintComma = false;
255     for (FunctionDecl::param_const_iterator I = D->param_begin(),
256            E = D->param_end(); I != E; ++I) {
257       if (PrintComma)
258         Out << ", ";
259       else
260         PrintComma = true;
261       Out << (*I)->getNameAsString();
262     }
263     Out << ")";
264
265     // Check the semantic DeclContext.
266     const DeclContext* SemaDC = D->getDeclContext();
267     const DeclContext* LexicalDC = D->getLexicalDeclContext();
268     if (SemaDC != LexicalDC)
269       Out << " [[" << SemaDC << "]]";
270
271     break;
272   }
273   case Decl::CXXConstructor: {
274     const CXXConstructorDecl* D = cast<CXXConstructorDecl>(DC);
275     if (D->isOutOfLine())
276       Out << "[c++ ctor] ";
277     else if (D->isImplicit())
278       Out << "(c++ ctor) ";
279     else
280       Out << "<c++ ctor> ";
281     Out << D->getNameAsString();
282     // Print the parameters.
283     Out << "(";
284     bool PrintComma = false;
285     for (FunctionDecl::param_const_iterator I = D->param_begin(),
286            E = D->param_end(); I != E; ++I) {
287       if (PrintComma)
288         Out << ", ";
289       else
290         PrintComma = true;
291       Out << (*I)->getNameAsString();
292     }
293     Out << ")";
294
295     // Check the semantic DC.
296     const DeclContext* SemaDC = D->getDeclContext();
297     const DeclContext* LexicalDC = D->getLexicalDeclContext();
298     if (SemaDC != LexicalDC)
299       Out << " [[" << SemaDC << "]]";
300     break;
301   }
302   case Decl::CXXDestructor: {
303     const CXXDestructorDecl* D = cast<CXXDestructorDecl>(DC);
304     if (D->isOutOfLine())
305       Out << "[c++ dtor] ";
306     else if (D->isImplicit())
307       Out << "(c++ dtor) ";
308     else
309       Out << "<c++ dtor> ";
310     Out << D->getNameAsString();
311     // Check the semantic DC.
312     const DeclContext* SemaDC = D->getDeclContext();
313     const DeclContext* LexicalDC = D->getLexicalDeclContext();
314     if (SemaDC != LexicalDC)
315       Out << " [[" << SemaDC << "]]";
316     break;
317   }
318   case Decl::CXXConversion: {
319     const CXXConversionDecl* D = cast<CXXConversionDecl>(DC);
320     if (D->isOutOfLine())
321       Out << "[c++ conversion] ";
322     else if (D->isImplicit())
323       Out << "(c++ conversion) ";
324     else
325       Out << "<c++ conversion> ";
326     Out << D->getNameAsString();
327     // Check the semantic DC.
328     const DeclContext* SemaDC = D->getDeclContext();
329     const DeclContext* LexicalDC = D->getLexicalDeclContext();
330     if (SemaDC != LexicalDC)
331       Out << " [[" << SemaDC << "]]";
332     break;
333   }
334
335   default:
336     assert(0 && "a decl that inherits DeclContext isn't handled");
337   }
338
339   Out << "\n";
340
341   // Print decls in the DeclContext.
342   for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
343        I != E; ++I) {
344     for (unsigned i = 0; i < Indentation; ++i)
345       Out << "  ";
346
347     Decl::Kind DK = I->getKind();
348     switch (DK) {
349     case Decl::Namespace:
350     case Decl::Enum:
351     case Decl::Record:
352     case Decl::CXXRecord:
353     case Decl::ObjCMethod:
354     case Decl::ObjCInterface:
355     case Decl::ObjCCategory:
356     case Decl::ObjCProtocol:
357     case Decl::ObjCImplementation:
358     case Decl::ObjCCategoryImpl:
359     case Decl::LinkageSpec:
360     case Decl::Block:
361     case Decl::Function:
362     case Decl::CXXMethod:
363     case Decl::CXXConstructor:
364     case Decl::CXXDestructor:
365     case Decl::CXXConversion:
366     {
367       DeclContext* DC = cast<DeclContext>(*I);
368       PrintDeclContext(DC, Indentation+2);
369       break;
370     }
371     case Decl::Field: {
372       FieldDecl* FD = cast<FieldDecl>(*I);
373       Out << "<field> " << FD->getNameAsString() << "\n";
374       break;
375     }
376     case Decl::Typedef: {
377       TypedefDecl* TD = cast<TypedefDecl>(*I);
378       Out << "<typedef> " << TD->getNameAsString() << "\n";
379       break;
380     }
381     case Decl::EnumConstant: {
382       EnumConstantDecl* ECD = cast<EnumConstantDecl>(*I);
383       Out << "<enum constant> " << ECD->getNameAsString() << "\n";
384       break;
385     }
386     case Decl::Var: {
387       VarDecl* VD = cast<VarDecl>(*I);
388       Out << "<var> " << VD->getNameAsString() << "\n";
389       break;
390     }
391     case Decl::ImplicitParam: {
392       ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(*I);
393       Out << "<implicit parameter> " << IPD->getNameAsString() << "\n";
394       break;
395     }
396     case Decl::ParmVar: {
397       ParmVarDecl* PVD = cast<ParmVarDecl>(*I);
398       Out << "<parameter> " << PVD->getNameAsString() << "\n";
399       break;
400     }
401     case Decl::ObjCProperty: {
402       ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(*I);
403       Out << "<objc property> " << OPD->getNameAsString() << "\n";
404       break;
405     }
406     case Decl::FunctionTemplate: {
407       FunctionTemplateDecl* FTD = cast<FunctionTemplateDecl>(*I);
408       Out << "<function template> " << FTD->getNameAsString() << "\n";
409       break;
410     }
411     case Decl::FileScopeAsm: {
412       Out << "<file-scope asm>\n";
413       break;
414     }
415     case Decl::UsingDirective: {
416       Out << "<using directive>\n";
417       break;
418     }
419     case Decl::NamespaceAlias: {
420       NamespaceAliasDecl* NAD = cast<NamespaceAliasDecl>(*I);
421       Out << "<namespace alias> " << NAD->getNameAsString() << "\n";
422       break;
423     }
424     default:
425       Out << "DeclKind: " << DK << '"' << I->getDeclKindName() << "\"\n";
426       assert(0 && "decl unhandled");
427     }
428   }
429 }
430 ASTConsumer *clang::CreateDeclContextPrinter() {
431   return new DeclContextPrinter();
432 }
433
434 //===----------------------------------------------------------------------===//
435 /// RecordLayoutDumper - C++ Record Layout Dumping.
436 namespace {
437 class RecordLayoutDumper : public ASTConsumer {
438   llvm::raw_ostream& Out;
439   
440   void PrintOffset(uint64_t Offset, unsigned IndentLevel) {
441     Out << llvm::format("%4d | ", Offset);
442     for (unsigned I = 0; I < IndentLevel * 2; ++I) Out << ' ';
443   }
444   
445   void DumpRecordLayoutOffsets(const CXXRecordDecl *RD, ASTContext &C,
446                                uint64_t Offset,
447                                unsigned IndentLevel, const char* Description,
448                                bool IncludeVirtualBases) {
449     const ASTRecordLayout &Info = C.getASTRecordLayout(RD);
450
451     PrintOffset(Offset, IndentLevel);
452     Out << C.getTypeDeclType((CXXRecordDecl *)RD).getAsString();
453     if (Description)
454       Out << ' ' << Description;
455     if (RD->isEmpty())
456       Out << " (empty)";
457     Out << '\n';
458     
459     IndentLevel++;
460     
461     const CXXRecordDecl *PrimaryBase = Info.getPrimaryBase();
462     
463     // Vtable pointer.
464     if (RD->isDynamicClass() && !PrimaryBase) {
465       PrintOffset(Offset, IndentLevel);
466       Out << '(' << RD->getNameAsString() << " vtable pointer)\n";
467     }
468     // Dump (non-virtual) bases
469     for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
470          E = RD->bases_end(); I != E; ++I) {
471       assert(!I->getType()->isDependentType() &&
472              "Cannot layout class with dependent bases.");
473       if (I->isVirtual())
474         continue;
475       
476       const CXXRecordDecl *Base =
477         cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
478       
479       uint64_t BaseOffset = Offset + Info.getBaseClassOffset(Base) / 8;
480       
481       DumpRecordLayoutOffsets(Base, C, BaseOffset, IndentLevel, 
482                               Base == PrimaryBase ? "(primary base)" : "(base)",
483                               /*IncludeVirtualBases=*/false);
484     }
485     
486     // Dump fields.
487     uint64_t FieldNo = 0;
488     for (CXXRecordDecl::field_iterator I = RD->field_begin(),
489          E = RD->field_end(); I != E; ++I, ++FieldNo) {      
490       const FieldDecl *Field = *I;
491       uint64_t FieldOffset = Offset + Info.getFieldOffset(FieldNo) / 8;
492       
493       if (const RecordType *RT = Field->getType()->getAs<RecordType>()) {
494         if (const CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
495           DumpRecordLayoutOffsets(D, C, FieldOffset, IndentLevel, 
496                                   Field->getNameAsCString(),
497                                   /*IncludeVirtualBases=*/true);
498           continue;
499         }
500       }
501       
502       PrintOffset(FieldOffset, IndentLevel);
503       Out << Field->getType().getAsString() << ' ';
504       Out << Field->getNameAsString() << '\n';
505     }
506     
507     if (!IncludeVirtualBases)
508       return;
509     
510     // Dump virtual bases.
511     for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
512          E = RD->vbases_end(); I != E; ++I) {
513       assert(I->isVirtual() && "Found non-virtual class!");
514       const CXXRecordDecl *VBase =
515         cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
516       
517       uint64_t VBaseOffset = Offset + Info.getVBaseClassOffset(VBase) / 8;
518       DumpRecordLayoutOffsets(VBase, C, VBaseOffset, IndentLevel, 
519                               VBase == PrimaryBase ? 
520                               "(primary virtual base)" : "(virtual base)",
521                               /*IncludeVirtualBases=*/false);
522     }
523   }
524   
525   // FIXME: Maybe this could be useful in ASTContext.cpp.
526   void DumpRecordLayout(const CXXRecordDecl *RD, ASTContext &C) {
527     const ASTRecordLayout &Info = C.getASTRecordLayout(RD);
528     
529     DumpRecordLayoutOffsets(RD, C, 0, 0, 0, 
530                             /*IncludeVirtualBases=*/true);
531     Out << "  sizeof=" << Info.getSize() / 8;
532     Out << ", dsize=" << Info.getDataSize() / 8;
533     Out << ", align=" << Info.getAlignment() / 8 << '\n';
534     Out << "  nvsize=" << Info.getNonVirtualSize() / 8;
535     Out << ", nvalign=" << Info.getNonVirtualAlign() / 8 << '\n';
536     Out << '\n';
537   }
538   
539 public:
540   RecordLayoutDumper() : Out(llvm::errs()) {}
541   
542   void HandleTranslationUnit(ASTContext &C) {
543     for (ASTContext::type_iterator I = C.types_begin(), E = C.types_end(); 
544          I != E; ++I) {
545       const RecordType *RT = dyn_cast<RecordType>(*I);
546       if (!RT)
547         continue;
548       
549       const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
550       if (!RD)
551         continue;
552       
553       if (RD->isImplicit())
554         continue;
555
556       if (RD->isDependentType())
557         continue;
558       
559       if (RD->isInvalidDecl())
560         continue;
561       
562       if (!RD->getDefinition(C))
563         continue;
564       
565       // FIXME: Do we really need to hard code this?
566       if (RD->getQualifiedNameAsString() == "__va_list_tag")
567         continue;
568       
569       DumpRecordLayout(RD, C);
570    }
571   }
572 };
573 } // end anonymous namespace
574 ASTConsumer *clang::CreateRecordLayoutDumper() {
575   return new RecordLayoutDumper();
576 }
577
578 //===----------------------------------------------------------------------===//
579 /// InheritanceViewer - C++ Inheritance Visualization
580
581 namespace {
582 class InheritanceViewer : public ASTConsumer {
583   const std::string clsname;
584 public:
585   InheritanceViewer(const std::string& cname) : clsname(cname) {}
586
587   void HandleTranslationUnit(ASTContext &C) {
588     for (ASTContext::type_iterator I=C.types_begin(),E=C.types_end(); I!=E; ++I)
589       if (RecordType *T = dyn_cast<RecordType>(*I)) {
590         if (CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(T->getDecl())) {
591           // FIXME: This lookup needs to be generalized to handle namespaces and
592           // (when we support them) templates.
593           if (D->getNameAsString() == clsname) {
594             D->viewInheritance(C);
595           }
596         }
597       }
598   }
599 };
600 }
601
602 ASTConsumer *clang::CreateInheritanceViewer(const std::string& clsname) {
603   return new InheritanceViewer(clsname);
604 }