1 //===--- DeclPrinter.cpp - Printing implementation for Decl ASTs ----------===//
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 // This file implements the Decl::dump method, which pretty print the
11 // AST back out to C/Objective-C/C++/Objective-C++ code.
12 //
13 //===----------------------------------------------------------------------===//
14 #include "clang/AST/ASTContext.h"
15 #include "clang/AST/DeclVisitor.h"
16 #include "clang/AST/Decl.h"
17 #include "clang/AST/DeclCXX.h"
18 #include "clang/AST/DeclObjC.h"
19 #include "clang/AST/Expr.h"
20 #include "clang/AST/ExprCXX.h"
21 #include "clang/AST/PrettyPrinter.h"
22 #include "llvm/Support/raw_ostream.h"
23 using namespace clang;
24 
25 namespace {
26   class DeclPrinter : public DeclVisitor<DeclPrinter> {
27     llvm::raw_ostream &Out;
28     ASTContext &Context;
29     PrintingPolicy Policy;
30     unsigned Indentation;
31 
32     llvm::raw_ostream& Indent() { return Indent(Indentation); }
33     llvm::raw_ostream& Indent(unsigned Indentation);
34     void ProcessDeclGroup(llvm::SmallVectorImpl<Decl*>& Decls);
35 
36     void Print(AccessSpecifier AS);
37 
38   public:
39     DeclPrinter(llvm::raw_ostream &Out, ASTContext &Context,
40                 const PrintingPolicy &Policy,
41                 unsigned Indentation = 0)
42       : Out(Out), Context(Context), Policy(Policy), Indentation(Indentation) { }
43 
44     void VisitDeclContext(DeclContext *DC, bool Indent = true);
45 
46     void VisitTranslationUnitDecl(TranslationUnitDecl *D);
47     void VisitTypedefDecl(TypedefDecl *D);
48     void VisitEnumDecl(EnumDecl *D);
49     void VisitRecordDecl(RecordDecl *D);
50     void VisitEnumConstantDecl(EnumConstantDecl *D);
51     void VisitFunctionDecl(FunctionDecl *D);
52     void VisitFieldDecl(FieldDecl *D);
53     void VisitVarDecl(VarDecl *D);
54     void VisitLabelDecl(LabelDecl *D);
55     void VisitParmVarDecl(ParmVarDecl *D);
56     void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
57     void VisitStaticAssertDecl(StaticAssertDecl *D);
58     void VisitNamespaceDecl(NamespaceDecl *D);
59     void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
60     void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
61     void VisitCXXRecordDecl(CXXRecordDecl *D);
62     void VisitLinkageSpecDecl(LinkageSpecDecl *D);
63     void VisitTemplateDecl(TemplateDecl *D);
64     void VisitObjCMethodDecl(ObjCMethodDecl *D);
65     void VisitObjCClassDecl(ObjCClassDecl *D);
66     void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
67     void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
68     void VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D);
69     void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
70     void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
71     void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
72     void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
73     void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
74     void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
75     void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
76     void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
77     void VisitUsingDecl(UsingDecl *D);
78     void VisitUsingShadowDecl(UsingShadowDecl *D);
79   };
80 }
81 
82 void Decl::print(llvm::raw_ostream &Out, unsigned Indentation) const {
83   print(Out, getASTContext().PrintingPolicy, Indentation);
84 }
85 
86 void Decl::print(llvm::raw_ostream &Out, const PrintingPolicy &Policy,
87                  unsigned Indentation) const {
88   DeclPrinter Printer(Out, getASTContext(), Policy, Indentation);
89   Printer.Visit(const_cast<Decl*>(this));
90 }
91 
92 static QualType GetBaseType(QualType T) {
93   // FIXME: This should be on the Type class!
94   QualType BaseType = T;
95   while (!BaseType->isSpecifierType()) {
96     if (isa<TypedefType>(BaseType))
97       break;
98     else if (const PointerType* PTy = BaseType->getAs<PointerType>())
99       BaseType = PTy->getPointeeType();
100     else if (const ArrayType* ATy = dyn_cast<ArrayType>(BaseType))
101       BaseType = ATy->getElementType();
102     else if (const FunctionType* FTy = BaseType->getAs<FunctionType>())
103       BaseType = FTy->getResultType();
104     else if (const VectorType *VTy = BaseType->getAs<VectorType>())
105       BaseType = VTy->getElementType();
106     else
107       assert(0 && "Unknown declarator!");
108   }
109   return BaseType;
110 }
111 
112 static QualType getDeclType(Decl* D) {
113   if (TypedefDecl* TDD = dyn_cast<TypedefDecl>(D))
114     return TDD->getUnderlyingType();
115   if (ValueDecl* VD = dyn_cast<ValueDecl>(D))
116     return VD->getType();
117   return QualType();
118 }
119 
120 void Decl::printGroup(Decl** Begin, unsigned NumDecls,
121                       llvm::raw_ostream &Out, const PrintingPolicy &Policy,
122                       unsigned Indentation) {
123   if (NumDecls == 1) {
124     (*Begin)->print(Out, Policy, Indentation);
125     return;
126   }
127 
128   Decl** End = Begin + NumDecls;
129   TagDecl* TD = dyn_cast<TagDecl>(*Begin);
130   if (TD)
131     ++Begin;
132 
133   PrintingPolicy SubPolicy(Policy);
134   if (TD && TD->isDefinition()) {
135     TD->print(Out, Policy, Indentation);
136     Out << " ";
137     SubPolicy.SuppressTag = true;
138   }
139 
140   bool isFirst = true;
141   for ( ; Begin != End; ++Begin) {
142     if (isFirst) {
143       SubPolicy.SuppressSpecifiers = false;
144       isFirst = false;
145     } else {
146       if (!isFirst) Out << ", ";
147       SubPolicy.SuppressSpecifiers = true;
148     }
149 
150     (*Begin)->print(Out, SubPolicy, Indentation);
151   }
152 }
153 
154 void DeclContext::dumpDeclContext() const {
155   // Get the translation unit
156   const DeclContext *DC = this;
157   while (!DC->isTranslationUnit())
158     DC = DC->getParent();
159 
160   ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
161   DeclPrinter Printer(llvm::errs(), Ctx, Ctx.PrintingPolicy, 0);
162   Printer.VisitDeclContext(const_cast<DeclContext *>(this), /*Indent=*/false);
163 }
164 
165 void Decl::dump() const {
166   print(llvm::errs());
167 }
168 
169 llvm::raw_ostream& DeclPrinter::Indent(unsigned Indentation) {
170   for (unsigned i = 0; i != Indentation; ++i)
171     Out << "  ";
172   return Out;
173 }
174 
175 void DeclPrinter::ProcessDeclGroup(llvm::SmallVectorImpl<Decl*>& Decls) {
176   this->Indent();
177   Decl::printGroup(Decls.data(), Decls.size(), Out, Policy, Indentation);
178   Out << ";\n";
179   Decls.clear();
180 
181 }
182 
183 void DeclPrinter::Print(AccessSpecifier AS) {
184   switch(AS) {
185   case AS_none:      assert(0 && "No access specifier!"); break;
186   case AS_public:    Out << "public"; break;
187   case AS_protected: Out << "protected"; break;
188   case AS_private:   Out << "private"; break;
189   }
190 }
191 
192 //----------------------------------------------------------------------------
193 // Common C declarations
194 //----------------------------------------------------------------------------
195 
196 void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
197   if (Indent)
198     Indentation += Policy.Indentation;
199 
200   llvm::SmallVector<Decl*, 2> Decls;
201   for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
202        D != DEnd; ++D) {
203 
204     // Don't print ObjCIvarDecls, as they are printed when visiting the
205     // containing ObjCInterfaceDecl.
206     if (isa<ObjCIvarDecl>(*D))
207       continue;
208 
209     if (!Policy.Dump) {
210       // Skip over implicit declarations in pretty-printing mode.
211       if (D->isImplicit()) continue;
212       // FIXME: Ugly hack so we don't pretty-print the builtin declaration
213       // of __builtin_va_list or __[u]int128_t.  There should be some other way
214       // to check that.
215       if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) {
216         if (IdentifierInfo *II = ND->getIdentifier()) {
217           if (II->isStr("__builtin_va_list") ||
218               II->isStr("__int128_t") || II->isStr("__uint128_t"))
219             continue;
220         }
221       }
222     }
223 
224     // The next bits of code handles stuff like "struct {int x;} a,b"; we're
225     // forced to merge the declarations because there's no other way to
226     // refer to the struct in question.  This limited merging is safe without
227     // a bunch of other checks because it only merges declarations directly
228     // referring to the tag, not typedefs.
229     //
230     // Check whether the current declaration should be grouped with a previous
231     // unnamed struct.
232     QualType CurDeclType = getDeclType(*D);
233     if (!Decls.empty() && !CurDeclType.isNull()) {
234       QualType BaseType = GetBaseType(CurDeclType);
235       if (!BaseType.isNull() && isa<TagType>(BaseType) &&
236           cast<TagType>(BaseType)->getDecl() == Decls[0]) {
237         Decls.push_back(*D);
238         continue;
239       }
240     }
241 
242     // If we have a merged group waiting to be handled, handle it now.
243     if (!Decls.empty())
244       ProcessDeclGroup(Decls);
245 
246     // If the current declaration is an unnamed tag type, save it
247     // so we can merge it with the subsequent declaration(s) using it.
248     if (isa<TagDecl>(*D) && !cast<TagDecl>(*D)->getIdentifier()) {
249       Decls.push_back(*D);
250       continue;
251     }
252 
253     if (isa<AccessSpecDecl>(*D)) {
254       Indentation -= Policy.Indentation;
255       this->Indent();
256       Print(D->getAccess());
257       Out << ":\n";
258       Indentation += Policy.Indentation;
259       continue;
260     }
261 
262     this->Indent();
263     Visit(*D);
264 
265     // FIXME: Need to be able to tell the DeclPrinter when
266     const char *Terminator = 0;
267     if (isa<FunctionDecl>(*D) &&
268         cast<FunctionDecl>(*D)->isThisDeclarationADefinition())
269       Terminator = 0;
270     else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->getBody())
271       Terminator = 0;
272     else if (isa<NamespaceDecl>(*D) || isa<LinkageSpecDecl>(*D) ||
273              isa<ObjCImplementationDecl>(*D) ||
274              isa<ObjCInterfaceDecl>(*D) ||
275              isa<ObjCProtocolDecl>(*D) ||
276              isa<ObjCCategoryImplDecl>(*D) ||
277              isa<ObjCCategoryDecl>(*D))
278       Terminator = 0;
279     else if (isa<EnumConstantDecl>(*D)) {
280       DeclContext::decl_iterator Next = D;
281       ++Next;
282       if (Next != DEnd)
283         Terminator = ",";
284     } else
285       Terminator = ";";
286 
287     if (Terminator)
288       Out << Terminator;
289     Out << "\n";
290   }
291 
292   if (!Decls.empty())
293     ProcessDeclGroup(Decls);
294 
295   if (Indent)
296     Indentation -= Policy.Indentation;
297 }
298 
299 void DeclPrinter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
300   VisitDeclContext(D, false);
301 }
302 
303 void DeclPrinter::VisitTypedefDecl(TypedefDecl *D) {
304   std::string S = D->getNameAsString();
305   D->getUnderlyingType().getAsStringInternal(S, Policy);
306   if (!Policy.SuppressSpecifiers)
307     Out << "typedef ";
308   Out << S;
309 }
310 
311 void DeclPrinter::VisitEnumDecl(EnumDecl *D) {
312   Out << "enum ";
313   if (D->isScoped()) {
314     if (D->isScopedUsingClassTag())
315       Out << "class ";
316     else
317       Out << "struct ";
318   }
319   Out << D;
320 
321   if (D->isFixed()) {
322     std::string Underlying;
323     D->getIntegerType().getAsStringInternal(Underlying, Policy);
324     Out << " : " << Underlying;
325   }
326 
327   if (D->isDefinition()) {
328     Out << " {\n";
329     VisitDeclContext(D);
330     Indent() << "}";
331   }
332 }
333 
334 void DeclPrinter::VisitRecordDecl(RecordDecl *D) {
335   Out << D->getKindName();
336   if (D->getIdentifier())
337     Out << ' ' << D;
338 
339   if (D->isDefinition()) {
340     Out << " {\n";
341     VisitDeclContext(D);
342     Indent() << "}";
343   }
344 }
345 
346 void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) {
347   Out << D;
348   if (Expr *Init = D->getInitExpr()) {
349     Out << " = ";
350     Init->printPretty(Out, Context, 0, Policy, Indentation);
351   }
352 }
353 
354 void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
355   if (!Policy.SuppressSpecifiers) {
356     switch (D->getStorageClass()) {
357     case SC_None: break;
358     case SC_Extern: Out << "extern "; break;
359     case SC_Static: Out << "static "; break;
360     case SC_PrivateExtern: Out << "__private_extern__ "; break;
361     case SC_Auto: case SC_Register: llvm_unreachable("invalid for functions");
362     }
363 
364     if (D->isInlineSpecified())           Out << "inline ";
365     if (D->isVirtualAsWritten()) Out << "virtual ";
366   }
367 
368   PrintingPolicy SubPolicy(Policy);
369   SubPolicy.SuppressSpecifiers = false;
370   std::string Proto = D->getNameInfo().getAsString();
371 
372   QualType Ty = D->getType();
373   while (const ParenType *PT = dyn_cast<ParenType>(Ty)) {
374     Proto = '(' + Proto + ')';
375     Ty = PT->getInnerType();
376   }
377 
378   if (isa<FunctionType>(Ty)) {
379     const FunctionType *AFT = Ty->getAs<FunctionType>();
380     const FunctionProtoType *FT = 0;
381     if (D->hasWrittenPrototype())
382       FT = dyn_cast<FunctionProtoType>(AFT);
383 
384     Proto += "(";
385     if (FT) {
386       llvm::raw_string_ostream POut(Proto);
387       DeclPrinter ParamPrinter(POut, Context, SubPolicy, Indentation);
388       for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
389         if (i) POut << ", ";
390         ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
391       }
392 
393       if (FT->isVariadic()) {
394         if (D->getNumParams()) POut << ", ";
395         POut << "...";
396       }
397     } else if (D->isThisDeclarationADefinition() && !D->hasPrototype()) {
398       for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
399         if (i)
400           Proto += ", ";
401         Proto += D->getParamDecl(i)->getNameAsString();
402       }
403     }
404 
405     Proto += ")";
406 
407     if (FT && FT->getTypeQuals()) {
408       unsigned TypeQuals = FT->getTypeQuals();
409       if (TypeQuals & Qualifiers::Const)
410         Proto += " const";
411       if (TypeQuals & Qualifiers::Volatile)
412         Proto += " volatile";
413       if (TypeQuals & Qualifiers::Restrict)
414         Proto += " restrict";
415     }
416 
417     if (FT && FT->hasDynamicExceptionSpec()) {
418       Proto += " throw(";
419       if (FT->getExceptionSpecType() == EST_MSAny)
420         Proto += "...";
421       else
422         for (unsigned I = 0, N = FT->getNumExceptions(); I != N; ++I) {
423           if (I)
424             Proto += ", ";
425 
426           std::string ExceptionType;
427           FT->getExceptionType(I).getAsStringInternal(ExceptionType, SubPolicy);
428           Proto += ExceptionType;
429         }
430       Proto += ")";
431     } else if (FT && isNoexceptExceptionSpec(FT->getExceptionSpecType())) {
432       Proto += " noexcept";
433       if (FT->getExceptionSpecType() == EST_ComputedNoexcept) {
434         Proto += "(";
435         llvm::raw_string_ostream EOut(Proto);
436         FT->getNoexceptExpr()->printPretty(EOut, Context, 0, SubPolicy,
437                                            Indentation);
438         EOut.flush();
439         Proto += EOut.str();
440         Proto += ")";
441       }
442     }
443 
444     if (D->hasAttr<NoReturnAttr>())
445       Proto += " __attribute((noreturn))";
446     if (CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D)) {
447       if (CDecl->getNumCtorInitializers() > 0) {
448         Proto += " : ";
449         Out << Proto;
450         Proto.clear();
451         for (CXXConstructorDecl::init_const_iterator B = CDecl->init_begin(),
452              E = CDecl->init_end();
453              B != E; ++B) {
454           CXXCtorInitializer * BMInitializer = (*B);
455           if (B != CDecl->init_begin())
456             Out << ", ";
457           if (BMInitializer->isAnyMemberInitializer()) {
458             FieldDecl *FD = BMInitializer->getAnyMember();
459             Out << FD;
460           } else {
461             Out << QualType(BMInitializer->getBaseClass(),
462                             0).getAsString(Policy);
463           }
464 
465           Out << "(";
466           if (!BMInitializer->getInit()) {
467             // Nothing to print
468           } else {
469             Expr *Init = BMInitializer->getInit();
470             if (ExprWithCleanups *Tmp = dyn_cast<ExprWithCleanups>(Init))
471               Init = Tmp->getSubExpr();
472 
473             Init = Init->IgnoreParens();
474 
475             Expr *SimpleInit = 0;
476             Expr **Args = 0;
477             unsigned NumArgs = 0;
478             if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
479               Args = ParenList->getExprs();
480               NumArgs = ParenList->getNumExprs();
481             } else if (CXXConstructExpr *Construct
482                                           = dyn_cast<CXXConstructExpr>(Init)) {
483               Args = Construct->getArgs();
484               NumArgs = Construct->getNumArgs();
485             } else
486               SimpleInit = Init;
487 
488             if (SimpleInit)
489               SimpleInit->printPretty(Out, Context, 0, Policy, Indentation);
490             else {
491               for (unsigned I = 0; I != NumArgs; ++I) {
492                 if (isa<CXXDefaultArgExpr>(Args[I]))
493                   break;
494 
495                 if (I)
496                   Out << ", ";
497                 Args[I]->printPretty(Out, Context, 0, Policy, Indentation);
498               }
499             }
500           }
501           Out << ")";
502         }
503       }
504     }
505     else
506       AFT->getResultType().getAsStringInternal(Proto, Policy);
507   } else {
508     Ty.getAsStringInternal(Proto, Policy);
509   }
510 
511   Out << Proto;
512 
513   if (D->isPure())
514     Out << " = 0";
515   else if (D->isDeleted())
516     Out << " = delete";
517   else if (D->isThisDeclarationADefinition()) {
518     if (!D->hasPrototype() && D->getNumParams()) {
519       // This is a K&R function definition, so we need to print the
520       // parameters.
521       Out << '\n';
522       DeclPrinter ParamPrinter(Out, Context, SubPolicy, Indentation);
523       Indentation += Policy.Indentation;
524       for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
525         Indent();
526         ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
527         Out << ";\n";
528       }
529       Indentation -= Policy.Indentation;
530     } else
531       Out << ' ';
532 
533     D->getBody()->printPretty(Out, Context, 0, SubPolicy, Indentation);
534     Out << '\n';
535   }
536 }
537 
538 void DeclPrinter::VisitFieldDecl(FieldDecl *D) {
539   if (!Policy.SuppressSpecifiers && D->isMutable())
540     Out << "mutable ";
541 
542   std::string Name = D->getNameAsString();
543   D->getType().getAsStringInternal(Name, Policy);
544   Out << Name;
545 
546   if (D->isBitField()) {
547     Out << " : ";
548     D->getBitWidth()->printPretty(Out, Context, 0, Policy, Indentation);
549   }
550 }
551 
552 void DeclPrinter::VisitLabelDecl(LabelDecl *D) {
553   Out << D->getNameAsString() << ":";
554 }
555 
556 
557 void DeclPrinter::VisitVarDecl(VarDecl *D) {
558   if (!Policy.SuppressSpecifiers && D->getStorageClass() != SC_None)
559     Out << VarDecl::getStorageClassSpecifierString(D->getStorageClass()) << " ";
560 
561   if (!Policy.SuppressSpecifiers && D->isThreadSpecified())
562     Out << "__thread ";
563 
564   std::string Name = D->getNameAsString();
565   QualType T = D->getType();
566   if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D))
567     T = Parm->getOriginalType();
568   T.getAsStringInternal(Name, Policy);
569   Out << Name;
570   Expr *Init = D->getInit();
571   if (!Policy.SuppressInitializers && Init) {
572     if (D->hasCXXDirectInitializer())
573       Out << "(";
574     else {
575         CXXConstructExpr *CCE = dyn_cast<CXXConstructExpr>(Init);
576         if (!CCE || CCE->getConstructor()->isCopyConstructor())
577           Out << " = ";
578     }
579     Init->printPretty(Out, Context, 0, Policy, Indentation);
580     if (D->hasCXXDirectInitializer())
581       Out << ")";
582   }
583 }
584 
585 void DeclPrinter::VisitParmVarDecl(ParmVarDecl *D) {
586   VisitVarDecl(D);
587 }
588 
589 void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
590   Out << "__asm (";
591   D->getAsmString()->printPretty(Out, Context, 0, Policy, Indentation);
592   Out << ")";
593 }
594 
595 void DeclPrinter::VisitStaticAssertDecl(StaticAssertDecl *D) {
596   Out << "static_assert(";
597   D->getAssertExpr()->printPretty(Out, Context, 0, Policy, Indentation);
598   Out << ", ";
599   D->getMessage()->printPretty(Out, Context, 0, Policy, Indentation);
600   Out << ")";
601 }
602 
603 //----------------------------------------------------------------------------
604 // C++ declarations
605 //----------------------------------------------------------------------------
606 void DeclPrinter::VisitNamespaceDecl(NamespaceDecl *D) {
607   Out << "namespace " << D << " {\n";
608   VisitDeclContext(D);
609   Indent() << "}";
610 }
611 
612 void DeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
613   Out << "using namespace ";
614   if (D->getQualifier())
615     D->getQualifier()->print(Out, Policy);
616   Out << D->getNominatedNamespaceAsWritten();
617 }
618 
619 void DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
620   Out << "namespace " << D << " = ";
621   if (D->getQualifier())
622     D->getQualifier()->print(Out, Policy);
623   Out << D->getAliasedNamespace();
624 }
625 
626 void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
627   Out << D->getKindName();
628   if (D->getIdentifier())
629     Out << ' ' << D;
630 
631   if (D->isDefinition()) {
632     // Print the base classes
633     if (D->getNumBases()) {
634       Out << " : ";
635       for (CXXRecordDecl::base_class_iterator Base = D->bases_begin(),
636              BaseEnd = D->bases_end(); Base != BaseEnd; ++Base) {
637         if (Base != D->bases_begin())
638           Out << ", ";
639 
640         if (Base->isVirtual())
641           Out << "virtual ";
642 
643         AccessSpecifier AS = Base->getAccessSpecifierAsWritten();
644         if (AS != AS_none)
645           Print(AS);
646         Out << " " << Base->getType().getAsString(Policy);
647       }
648     }
649 
650     // Print the class definition
651     // FIXME: Doesn't print access specifiers, e.g., "public:"
652     Out << " {\n";
653     VisitDeclContext(D);
654     Indent() << "}";
655   }
656 }
657 
658 void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
659   const char *l;
660   if (D->getLanguage() == LinkageSpecDecl::lang_c)
661     l = "C";
662   else {
663     assert(D->getLanguage() == LinkageSpecDecl::lang_cxx &&
664            "unknown language in linkage specification");
665     l = "C++";
666   }
667 
668   Out << "extern \"" << l << "\" ";
669   if (D->hasBraces()) {
670     Out << "{\n";
671     VisitDeclContext(D);
672     Indent() << "}";
673   } else
674     Visit(*D->decls_begin());
675 }
676 
677 void DeclPrinter::VisitTemplateDecl(TemplateDecl *D) {
678   Out << "template <";
679 
680   TemplateParameterList *Params = D->getTemplateParameters();
681   for (unsigned i = 0, e = Params->size(); i != e; ++i) {
682     if (i != 0)
683       Out << ", ";
684 
685     const Decl *Param = Params->getParam(i);
686     if (const TemplateTypeParmDecl *TTP =
687           dyn_cast<TemplateTypeParmDecl>(Param)) {
688 
689       QualType ParamType =
690         Context.getTypeDeclType(const_cast<TemplateTypeParmDecl*>(TTP));
691 
692       if (TTP->wasDeclaredWithTypename())
693         Out << "typename ";
694       else
695         Out << "class ";
696 
697       if (TTP->isParameterPack())
698         Out << "... ";
699 
700       Out << ParamType.getAsString(Policy);
701 
702       if (TTP->hasDefaultArgument()) {
703         Out << " = ";
704         Out << TTP->getDefaultArgument().getAsString(Policy);
705       };
706     } else if (const NonTypeTemplateParmDecl *NTTP =
707                  dyn_cast<NonTypeTemplateParmDecl>(Param)) {
708       Out << NTTP->getType().getAsString(Policy);
709 
710       if (NTTP->isParameterPack() && !isa<PackExpansionType>(NTTP->getType()))
711         Out << "...";
712 
713       if (IdentifierInfo *Name = NTTP->getIdentifier()) {
714         Out << ' ';
715         Out << Name->getName();
716       }
717 
718       if (NTTP->hasDefaultArgument()) {
719         Out << " = ";
720         NTTP->getDefaultArgument()->printPretty(Out, Context, 0, Policy,
721                                                 Indentation);
722       }
723     }
724   }
725 
726   Out << "> ";
727 
728   if (TemplateTemplateParmDecl *TTP = dyn_cast<TemplateTemplateParmDecl>(D)) {
729     Out << "class ";
730     if (TTP->isParameterPack())
731       Out << "...";
732     Out << D->getName();
733   } else {
734     Visit(D->getTemplatedDecl());
735   }
736 }
737 
738 //----------------------------------------------------------------------------
739 // Objective-C declarations
740 //----------------------------------------------------------------------------
741 
742 void DeclPrinter::VisitObjCClassDecl(ObjCClassDecl *D) {
743   Out << "@class ";
744   for (ObjCClassDecl::iterator I = D->begin(), E = D->end();
745        I != E; ++I) {
746     if (I != D->begin()) Out << ", ";
747     Out << I->getInterface();
748   }
749 }
750 
751 void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) {
752   if (OMD->isInstanceMethod())
753     Out << "- ";
754   else
755     Out << "+ ";
756   if (!OMD->getResultType().isNull())
757     Out << '(' << OMD->getResultType().getAsString(Policy) << ")";
758 
759   std::string name = OMD->getSelector().getAsString();
760   std::string::size_type pos, lastPos = 0;
761   for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(),
762        E = OMD->param_end(); PI != E; ++PI) {
763     // FIXME: selector is missing here!
764     pos = name.find_first_of(":", lastPos);
765     Out << " " << name.substr(lastPos, pos - lastPos);
766     Out << ":(" << (*PI)->getType().getAsString(Policy) << ')' << *PI;
767     lastPos = pos + 1;
768   }
769 
770   if (OMD->param_begin() == OMD->param_end())
771     Out << " " << name;
772 
773   if (OMD->isVariadic())
774       Out << ", ...";
775 
776   if (OMD->getBody()) {
777     Out << ' ';
778     OMD->getBody()->printPretty(Out, Context, 0, Policy);
779     Out << '\n';
780   }
781 }
782 
783 void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) {
784   std::string I = OID->getNameAsString();
785   ObjCInterfaceDecl *SID = OID->getSuperClass();
786 
787   if (SID)
788     Out << "@implementation " << I << " : " << SID;
789   else
790     Out << "@implementation " << I;
791   Out << "\n";
792   VisitDeclContext(OID, false);
793   Out << "@end";
794 }
795 
796 void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
797   std::string I = OID->getNameAsString();
798   ObjCInterfaceDecl *SID = OID->getSuperClass();
799 
800   if (SID)
801     Out << "@interface " << I << " : " << SID;
802   else
803     Out << "@interface " << I;
804 
805   // Protocols?
806   const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();
807   if (!Protocols.empty()) {
808     for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
809          E = Protocols.end(); I != E; ++I)
810       Out << (I == Protocols.begin() ? '<' : ',') << *I;
811   }
812 
813   if (!Protocols.empty())
814     Out << "> ";
815 
816   if (OID->ivar_size() > 0) {
817     Out << "{\n";
818     Indentation += Policy.Indentation;
819     for (ObjCInterfaceDecl::ivar_iterator I = OID->ivar_begin(),
820          E = OID->ivar_end(); I != E; ++I) {
821       Indent() << (*I)->getType().getAsString(Policy) << ' ' << *I << ";\n";
822     }
823     Indentation -= Policy.Indentation;
824     Out << "}\n";
825   }
826 
827   VisitDeclContext(OID, false);
828   Out << "@end";
829   // FIXME: implement the rest...
830 }
831 
832 void DeclPrinter::VisitObjCForwardProtocolDecl(ObjCForwardProtocolDecl *D) {
833   Out << "@protocol ";
834   for (ObjCForwardProtocolDecl::protocol_iterator I = D->protocol_begin(),
835          E = D->protocol_end();
836        I != E; ++I) {
837     if (I != D->protocol_begin()) Out << ", ";
838     Out << *I;
839   }
840 }
841 
842 void DeclPrinter::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
843   Out << "@protocol " << PID << '\n';
844   VisitDeclContext(PID, false);
845   Out << "@end";
846 }
847 
848 void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) {
849   Out << "@implementation " << PID->getClassInterface() << '(' << PID << ")\n";
850 
851   VisitDeclContext(PID, false);
852   Out << "@end";
853   // FIXME: implement the rest...
854 }
855 
856 void DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) {
857   Out << "@interface " << PID->getClassInterface() << '(' << PID << ")\n";
858   VisitDeclContext(PID, false);
859   Out << "@end";
860 
861   // FIXME: implement the rest...
862 }
863 
864 void DeclPrinter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID) {
865   Out << "@compatibility_alias " << AID
866       << ' ' << AID->getClassInterface() << ";\n";
867 }
868 
869 /// PrintObjCPropertyDecl - print a property declaration.
870 ///
871 void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
872   if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Required)
873     Out << "@required\n";
874   else if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Optional)
875     Out << "@optional\n";
876 
877   Out << "@property";
878   if (PDecl->getPropertyAttributes() != ObjCPropertyDecl::OBJC_PR_noattr) {
879     bool first = true;
880     Out << " (";
881     if (PDecl->getPropertyAttributes() &
882         ObjCPropertyDecl::OBJC_PR_readonly) {
883       Out << (first ? ' ' : ',') << "readonly";
884       first = false;
885   }
886 
887   if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) {
888     Out << (first ? ' ' : ',') << "getter = "
889         << PDecl->getGetterName().getAsString();
890     first = false;
891   }
892   if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) {
893     Out << (first ? ' ' : ',') << "setter = "
894         << PDecl->getSetterName().getAsString();
895     first = false;
896   }
897 
898   if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_assign) {
899     Out << (first ? ' ' : ',') << "assign";
900     first = false;
901   }
902 
903   if (PDecl->getPropertyAttributes() &
904       ObjCPropertyDecl::OBJC_PR_readwrite) {
905     Out << (first ? ' ' : ',') << "readwrite";
906     first = false;
907   }
908 
909   if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) {
910     Out << (first ? ' ' : ',') << "retain";
911     first = false;
912   }
913 
914   if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) {
915     Out << (first ? ' ' : ',') << "copy";
916     first = false;
917   }
918 
919   if (PDecl->getPropertyAttributes() &
920       ObjCPropertyDecl::OBJC_PR_nonatomic) {
921     Out << (first ? ' ' : ',') << "nonatomic";
922     first = false;
923   }
924   Out << " )";
925   }
926   Out << ' ' << PDecl->getType().getAsString(Policy) << ' ' << PDecl;
927 }
928 
929 void DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) {
930   if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
931     Out << "@synthesize ";
932   else
933     Out << "@dynamic ";
934   Out << PID->getPropertyDecl();
935   if (PID->getPropertyIvarDecl())
936     Out << '=' << PID->getPropertyIvarDecl();
937 }
938 
939 void DeclPrinter::VisitUsingDecl(UsingDecl *D) {
940   Out << "using ";
941   D->getQualifier()->print(Out, Policy);
942   Out << D;
943 }
944 
945 void
946 DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
947   Out << "using typename ";
948   D->getQualifier()->print(Out, Policy);
949   Out << D->getDeclName();
950 }
951 
952 void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
953   Out << "using ";
954   D->getQualifier()->print(Out, Policy);
955   Out << D->getDeclName();
956 }
957 
958 void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) {
959   // ignore
960 }
961