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::print method, which pretty prints 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/Attr.h"
16#include "clang/AST/Decl.h"
17#include "clang/AST/DeclCXX.h"
18#include "clang/AST/DeclObjC.h"
19#include "clang/AST/DeclVisitor.h"
20#include "clang/AST/Expr.h"
21#include "clang/AST/ExprCXX.h"
22#include "clang/AST/PrettyPrinter.h"
23#include "clang/Basic/Module.h"
24#include "llvm/Support/raw_ostream.h"
25using namespace clang;
26
27namespace {
28  class DeclPrinter : public DeclVisitor<DeclPrinter> {
29    raw_ostream &Out;
30    PrintingPolicy Policy;
31    unsigned Indentation;
32    bool PrintInstantiation;
33
34    raw_ostream& Indent() { return Indent(Indentation); }
35    raw_ostream& Indent(unsigned Indentation);
36    void ProcessDeclGroup(SmallVectorImpl<Decl*>& Decls);
37
38    void Print(AccessSpecifier AS);
39
40  public:
41    DeclPrinter(raw_ostream &Out, const PrintingPolicy &Policy,
42                unsigned Indentation = 0, bool PrintInstantiation = false)
43      : Out(Out), Policy(Policy), Indentation(Indentation),
44        PrintInstantiation(PrintInstantiation) { }
45
46    void VisitDeclContext(DeclContext *DC, bool Indent = true);
47
48    void VisitTranslationUnitDecl(TranslationUnitDecl *D);
49    void VisitTypedefDecl(TypedefDecl *D);
50    void VisitTypeAliasDecl(TypeAliasDecl *D);
51    void VisitEnumDecl(EnumDecl *D);
52    void VisitRecordDecl(RecordDecl *D);
53    void VisitEnumConstantDecl(EnumConstantDecl *D);
54    void VisitEmptyDecl(EmptyDecl *D);
55    void VisitFunctionDecl(FunctionDecl *D);
56    void VisitFriendDecl(FriendDecl *D);
57    void VisitFieldDecl(FieldDecl *D);
58    void VisitVarDecl(VarDecl *D);
59    void VisitLabelDecl(LabelDecl *D);
60    void VisitParmVarDecl(ParmVarDecl *D);
61    void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
62    void VisitImportDecl(ImportDecl *D);
63    void VisitStaticAssertDecl(StaticAssertDecl *D);
64    void VisitNamespaceDecl(NamespaceDecl *D);
65    void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
66    void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
67    void VisitCXXRecordDecl(CXXRecordDecl *D);
68    void VisitLinkageSpecDecl(LinkageSpecDecl *D);
69    void VisitTemplateDecl(const TemplateDecl *D);
70    void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
71    void VisitClassTemplateDecl(ClassTemplateDecl *D);
72    void VisitObjCMethodDecl(ObjCMethodDecl *D);
73    void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
74    void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
75    void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
76    void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
77    void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
78    void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
79    void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
80    void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
81    void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
82    void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
83    void VisitUsingDecl(UsingDecl *D);
84    void VisitUsingShadowDecl(UsingShadowDecl *D);
85    void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
86
87    void PrintTemplateParameters(const TemplateParameterList *Params,
88                                 const TemplateArgumentList *Args = nullptr);
89    void prettyPrintAttributes(Decl *D);
90    void printDeclType(QualType T, StringRef DeclName, bool Pack = false);
91  };
92}
93
94void Decl::print(raw_ostream &Out, unsigned Indentation,
95                 bool PrintInstantiation) const {
96  print(Out, getASTContext().getPrintingPolicy(), Indentation, PrintInstantiation);
97}
98
99void Decl::print(raw_ostream &Out, const PrintingPolicy &Policy,
100                 unsigned Indentation, bool PrintInstantiation) const {
101  DeclPrinter Printer(Out, Policy, Indentation, PrintInstantiation);
102  Printer.Visit(const_cast<Decl*>(this));
103}
104
105static QualType GetBaseType(QualType T) {
106  // FIXME: This should be on the Type class!
107  QualType BaseType = T;
108  while (!BaseType->isSpecifierType()) {
109    if (isa<TypedefType>(BaseType))
110      break;
111    else if (const PointerType* PTy = BaseType->getAs<PointerType>())
112      BaseType = PTy->getPointeeType();
113    else if (const BlockPointerType *BPy = BaseType->getAs<BlockPointerType>())
114      BaseType = BPy->getPointeeType();
115    else if (const ArrayType* ATy = dyn_cast<ArrayType>(BaseType))
116      BaseType = ATy->getElementType();
117    else if (const FunctionType* FTy = BaseType->getAs<FunctionType>())
118      BaseType = FTy->getReturnType();
119    else if (const VectorType *VTy = BaseType->getAs<VectorType>())
120      BaseType = VTy->getElementType();
121    else if (const ReferenceType *RTy = BaseType->getAs<ReferenceType>())
122      BaseType = RTy->getPointeeType();
123    else
124      llvm_unreachable("Unknown declarator!");
125  }
126  return BaseType;
127}
128
129static QualType getDeclType(Decl* D) {
130  if (TypedefNameDecl* TDD = dyn_cast<TypedefNameDecl>(D))
131    return TDD->getUnderlyingType();
132  if (ValueDecl* VD = dyn_cast<ValueDecl>(D))
133    return VD->getType();
134  return QualType();
135}
136
137void Decl::printGroup(Decl** Begin, unsigned NumDecls,
138                      raw_ostream &Out, const PrintingPolicy &Policy,
139                      unsigned Indentation) {
140  if (NumDecls == 1) {
141    (*Begin)->print(Out, Policy, Indentation);
142    return;
143  }
144
145  Decl** End = Begin + NumDecls;
146  TagDecl* TD = dyn_cast<TagDecl>(*Begin);
147  if (TD)
148    ++Begin;
149
150  PrintingPolicy SubPolicy(Policy);
151  if (TD && TD->isCompleteDefinition()) {
152    TD->print(Out, Policy, Indentation);
153    Out << " ";
154    SubPolicy.SuppressTag = true;
155  }
156
157  bool isFirst = true;
158  for ( ; Begin != End; ++Begin) {
159    if (isFirst) {
160      SubPolicy.SuppressSpecifiers = false;
161      isFirst = false;
162    } else {
163      if (!isFirst) Out << ", ";
164      SubPolicy.SuppressSpecifiers = true;
165    }
166
167    (*Begin)->print(Out, SubPolicy, Indentation);
168  }
169}
170
171LLVM_DUMP_METHOD void DeclContext::dumpDeclContext() const {
172  // Get the translation unit
173  const DeclContext *DC = this;
174  while (!DC->isTranslationUnit())
175    DC = DC->getParent();
176
177  ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
178  DeclPrinter Printer(llvm::errs(), Ctx.getPrintingPolicy(), 0);
179  Printer.VisitDeclContext(const_cast<DeclContext *>(this), /*Indent=*/false);
180}
181
182raw_ostream& DeclPrinter::Indent(unsigned Indentation) {
183  for (unsigned i = 0; i != Indentation; ++i)
184    Out << "  ";
185  return Out;
186}
187
188void DeclPrinter::prettyPrintAttributes(Decl *D) {
189  if (Policy.PolishForDeclaration)
190    return;
191
192  if (D->hasAttrs()) {
193    AttrVec &Attrs = D->getAttrs();
194    for (AttrVec::const_iterator i=Attrs.begin(), e=Attrs.end(); i!=e; ++i) {
195      Attr *A = *i;
196      A->printPretty(Out, Policy);
197    }
198  }
199}
200
201void DeclPrinter::printDeclType(QualType T, StringRef DeclName, bool Pack) {
202  // Normally, a PackExpansionType is written as T[3]... (for instance, as a
203  // template argument), but if it is the type of a declaration, the ellipsis
204  // is placed before the name being declared.
205  if (auto *PET = T->getAs<PackExpansionType>()) {
206    Pack = true;
207    T = PET->getPattern();
208  }
209  T.print(Out, Policy, (Pack ? "..." : "") + DeclName);
210}
211
212void DeclPrinter::ProcessDeclGroup(SmallVectorImpl<Decl*>& Decls) {
213  this->Indent();
214  Decl::printGroup(Decls.data(), Decls.size(), Out, Policy, Indentation);
215  Out << ";\n";
216  Decls.clear();
217
218}
219
220void DeclPrinter::Print(AccessSpecifier AS) {
221  switch(AS) {
222  case AS_none:      llvm_unreachable("No access specifier!");
223  case AS_public:    Out << "public"; break;
224  case AS_protected: Out << "protected"; break;
225  case AS_private:   Out << "private"; break;
226  }
227}
228
229//----------------------------------------------------------------------------
230// Common C declarations
231//----------------------------------------------------------------------------
232
233void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
234  if (Policy.TerseOutput)
235    return;
236
237  if (Indent)
238    Indentation += Policy.Indentation;
239
240  SmallVector<Decl*, 2> Decls;
241  for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
242       D != DEnd; ++D) {
243
244    // Don't print ObjCIvarDecls, as they are printed when visiting the
245    // containing ObjCInterfaceDecl.
246    if (isa<ObjCIvarDecl>(*D))
247      continue;
248
249    // Skip over implicit declarations in pretty-printing mode.
250    if (D->isImplicit())
251      continue;
252
253    // The next bits of code handles stuff like "struct {int x;} a,b"; we're
254    // forced to merge the declarations because there's no other way to
255    // refer to the struct in question.  This limited merging is safe without
256    // a bunch of other checks because it only merges declarations directly
257    // referring to the tag, not typedefs.
258    //
259    // Check whether the current declaration should be grouped with a previous
260    // unnamed struct.
261    QualType CurDeclType = getDeclType(*D);
262    if (!Decls.empty() && !CurDeclType.isNull()) {
263      QualType BaseType = GetBaseType(CurDeclType);
264      if (!BaseType.isNull() && isa<ElaboratedType>(BaseType))
265        BaseType = cast<ElaboratedType>(BaseType)->getNamedType();
266      if (!BaseType.isNull() && isa<TagType>(BaseType) &&
267          cast<TagType>(BaseType)->getDecl() == Decls[0]) {
268        Decls.push_back(*D);
269        continue;
270      }
271    }
272
273    // If we have a merged group waiting to be handled, handle it now.
274    if (!Decls.empty())
275      ProcessDeclGroup(Decls);
276
277    // If the current declaration is an unnamed tag type, save it
278    // so we can merge it with the subsequent declaration(s) using it.
279    if (isa<TagDecl>(*D) && !cast<TagDecl>(*D)->getIdentifier()) {
280      Decls.push_back(*D);
281      continue;
282    }
283
284    if (isa<AccessSpecDecl>(*D)) {
285      Indentation -= Policy.Indentation;
286      this->Indent();
287      Print(D->getAccess());
288      Out << ":\n";
289      Indentation += Policy.Indentation;
290      continue;
291    }
292
293    this->Indent();
294    Visit(*D);
295
296    // FIXME: Need to be able to tell the DeclPrinter when
297    const char *Terminator = nullptr;
298    if (isa<OMPThreadPrivateDecl>(*D))
299      Terminator = nullptr;
300    else if (isa<FunctionDecl>(*D) &&
301             cast<FunctionDecl>(*D)->isThisDeclarationADefinition())
302      Terminator = nullptr;
303    else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->getBody())
304      Terminator = nullptr;
305    else if (isa<NamespaceDecl>(*D) || isa<LinkageSpecDecl>(*D) ||
306             isa<ObjCImplementationDecl>(*D) ||
307             isa<ObjCInterfaceDecl>(*D) ||
308             isa<ObjCProtocolDecl>(*D) ||
309             isa<ObjCCategoryImplDecl>(*D) ||
310             isa<ObjCCategoryDecl>(*D))
311      Terminator = nullptr;
312    else if (isa<EnumConstantDecl>(*D)) {
313      DeclContext::decl_iterator Next = D;
314      ++Next;
315      if (Next != DEnd)
316        Terminator = ",";
317    } else
318      Terminator = ";";
319
320    if (Terminator)
321      Out << Terminator;
322    Out << "\n";
323  }
324
325  if (!Decls.empty())
326    ProcessDeclGroup(Decls);
327
328  if (Indent)
329    Indentation -= Policy.Indentation;
330}
331
332void DeclPrinter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
333  VisitDeclContext(D, false);
334}
335
336void DeclPrinter::VisitTypedefDecl(TypedefDecl *D) {
337  if (!Policy.SuppressSpecifiers) {
338    Out << "typedef ";
339
340    if (D->isModulePrivate())
341      Out << "__module_private__ ";
342  }
343  D->getTypeSourceInfo()->getType().print(Out, Policy, D->getName());
344  prettyPrintAttributes(D);
345}
346
347void DeclPrinter::VisitTypeAliasDecl(TypeAliasDecl *D) {
348  Out << "using " << *D;
349  prettyPrintAttributes(D);
350  Out << " = " << D->getTypeSourceInfo()->getType().getAsString(Policy);
351}
352
353void DeclPrinter::VisitEnumDecl(EnumDecl *D) {
354  if (!Policy.SuppressSpecifiers && D->isModulePrivate())
355    Out << "__module_private__ ";
356  Out << "enum ";
357  if (D->isScoped()) {
358    if (D->isScopedUsingClassTag())
359      Out << "class ";
360    else
361      Out << "struct ";
362  }
363  Out << *D;
364
365  if (D->isFixed())
366    Out << " : " << D->getIntegerType().stream(Policy);
367
368  if (D->isCompleteDefinition()) {
369    Out << " {\n";
370    VisitDeclContext(D);
371    Indent() << "}";
372  }
373  prettyPrintAttributes(D);
374}
375
376void DeclPrinter::VisitRecordDecl(RecordDecl *D) {
377  if (!Policy.SuppressSpecifiers && D->isModulePrivate())
378    Out << "__module_private__ ";
379  Out << D->getKindName();
380
381  prettyPrintAttributes(D);
382
383  if (D->getIdentifier())
384    Out << ' ' << *D;
385
386  if (D->isCompleteDefinition()) {
387    Out << " {\n";
388    VisitDeclContext(D);
389    Indent() << "}";
390  }
391}
392
393void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) {
394  Out << *D;
395  if (Expr *Init = D->getInitExpr()) {
396    Out << " = ";
397    Init->printPretty(Out, nullptr, Policy, Indentation);
398  }
399}
400
401void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
402  CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
403  CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
404  if (!Policy.SuppressSpecifiers) {
405    switch (D->getStorageClass()) {
406    case SC_None: break;
407    case SC_Extern: Out << "extern "; break;
408    case SC_Static: Out << "static "; break;
409    case SC_PrivateExtern: Out << "__private_extern__ "; break;
410    case SC_Auto: case SC_Register: case SC_OpenCLWorkGroupLocal:
411      llvm_unreachable("invalid for functions");
412    }
413
414    if (D->isInlineSpecified())  Out << "inline ";
415    if (D->isVirtualAsWritten()) Out << "virtual ";
416    if (D->isModulePrivate())    Out << "__module_private__ ";
417    if (D->isConstexpr() && !D->isExplicitlyDefaulted()) Out << "constexpr ";
418    if ((CDecl && CDecl->isExplicitSpecified()) ||
419        (ConversionDecl && ConversionDecl->isExplicit()))
420      Out << "explicit ";
421  }
422
423  PrintingPolicy SubPolicy(Policy);
424  SubPolicy.SuppressSpecifiers = false;
425  std::string Proto = D->getNameInfo().getAsString();
426
427  QualType Ty = D->getType();
428  while (const ParenType *PT = dyn_cast<ParenType>(Ty)) {
429    Proto = '(' + Proto + ')';
430    Ty = PT->getInnerType();
431  }
432
433  if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
434    const FunctionProtoType *FT = nullptr;
435    if (D->hasWrittenPrototype())
436      FT = dyn_cast<FunctionProtoType>(AFT);
437
438    Proto += "(";
439    if (FT) {
440      llvm::raw_string_ostream POut(Proto);
441      DeclPrinter ParamPrinter(POut, SubPolicy, Indentation);
442      for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
443        if (i) POut << ", ";
444        ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
445      }
446
447      if (FT->isVariadic()) {
448        if (D->getNumParams()) POut << ", ";
449        POut << "...";
450      }
451    } else if (D->doesThisDeclarationHaveABody() && !D->hasPrototype()) {
452      for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
453        if (i)
454          Proto += ", ";
455        Proto += D->getParamDecl(i)->getNameAsString();
456      }
457    }
458
459    Proto += ")";
460
461    if (FT) {
462      if (FT->isConst())
463        Proto += " const";
464      if (FT->isVolatile())
465        Proto += " volatile";
466      if (FT->isRestrict())
467        Proto += " restrict";
468
469      switch (FT->getRefQualifier()) {
470      case RQ_None:
471        break;
472      case RQ_LValue:
473        Proto += " &";
474        break;
475      case RQ_RValue:
476        Proto += " &&";
477        break;
478      }
479    }
480
481    if (FT && FT->hasDynamicExceptionSpec()) {
482      Proto += " throw(";
483      if (FT->getExceptionSpecType() == EST_MSAny)
484        Proto += "...";
485      else
486        for (unsigned I = 0, N = FT->getNumExceptions(); I != N; ++I) {
487          if (I)
488            Proto += ", ";
489
490          Proto += FT->getExceptionType(I).getAsString(SubPolicy);
491        }
492      Proto += ")";
493    } else if (FT && isNoexceptExceptionSpec(FT->getExceptionSpecType())) {
494      Proto += " noexcept";
495      if (FT->getExceptionSpecType() == EST_ComputedNoexcept) {
496        Proto += "(";
497        llvm::raw_string_ostream EOut(Proto);
498        FT->getNoexceptExpr()->printPretty(EOut, nullptr, SubPolicy,
499                                           Indentation);
500        EOut.flush();
501        Proto += EOut.str();
502        Proto += ")";
503      }
504    }
505
506    if (CDecl) {
507      bool HasInitializerList = false;
508      for (const auto *BMInitializer : CDecl->inits()) {
509        if (BMInitializer->isInClassMemberInitializer())
510          continue;
511
512        if (!HasInitializerList) {
513          Proto += " : ";
514          Out << Proto;
515          Proto.clear();
516          HasInitializerList = true;
517        } else
518          Out << ", ";
519
520        if (BMInitializer->isAnyMemberInitializer()) {
521          FieldDecl *FD = BMInitializer->getAnyMember();
522          Out << *FD;
523        } else {
524          Out << QualType(BMInitializer->getBaseClass(), 0).getAsString(Policy);
525        }
526
527        Out << "(";
528        if (!BMInitializer->getInit()) {
529          // Nothing to print
530        } else {
531          Expr *Init = BMInitializer->getInit();
532          if (ExprWithCleanups *Tmp = dyn_cast<ExprWithCleanups>(Init))
533            Init = Tmp->getSubExpr();
534
535          Init = Init->IgnoreParens();
536
537          Expr *SimpleInit = nullptr;
538          Expr **Args = nullptr;
539          unsigned NumArgs = 0;
540          if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
541            Args = ParenList->getExprs();
542            NumArgs = ParenList->getNumExprs();
543          } else if (CXXConstructExpr *Construct
544                                        = dyn_cast<CXXConstructExpr>(Init)) {
545            Args = Construct->getArgs();
546            NumArgs = Construct->getNumArgs();
547          } else
548            SimpleInit = Init;
549
550          if (SimpleInit)
551            SimpleInit->printPretty(Out, nullptr, Policy, Indentation);
552          else {
553            for (unsigned I = 0; I != NumArgs; ++I) {
554              assert(Args[I] != nullptr && "Expected non-null Expr");
555              if (isa<CXXDefaultArgExpr>(Args[I]))
556                break;
557
558              if (I)
559                Out << ", ";
560              Args[I]->printPretty(Out, nullptr, Policy, Indentation);
561            }
562          }
563        }
564        Out << ")";
565        if (BMInitializer->isPackExpansion())
566          Out << "...";
567      }
568    } else if (!ConversionDecl && !isa<CXXDestructorDecl>(D)) {
569      if (FT && FT->hasTrailingReturn()) {
570        Out << "auto " << Proto << " -> ";
571        Proto.clear();
572      }
573      AFT->getReturnType().print(Out, Policy, Proto);
574      Proto.clear();
575    }
576    Out << Proto;
577  } else {
578    Ty.print(Out, Policy, Proto);
579  }
580
581  prettyPrintAttributes(D);
582
583  if (D->isPure())
584    Out << " = 0";
585  else if (D->isDeletedAsWritten())
586    Out << " = delete";
587  else if (D->isExplicitlyDefaulted())
588    Out << " = default";
589  else if (D->doesThisDeclarationHaveABody() && !Policy.TerseOutput) {
590    if (!D->hasPrototype() && D->getNumParams()) {
591      // This is a K&R function definition, so we need to print the
592      // parameters.
593      Out << '\n';
594      DeclPrinter ParamPrinter(Out, SubPolicy, Indentation);
595      Indentation += Policy.Indentation;
596      for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
597        Indent();
598        ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
599        Out << ";\n";
600      }
601      Indentation -= Policy.Indentation;
602    } else
603      Out << ' ';
604
605    if (D->getBody())
606      D->getBody()->printPretty(Out, nullptr, SubPolicy, Indentation);
607    Out << '\n';
608  }
609}
610
611void DeclPrinter::VisitFriendDecl(FriendDecl *D) {
612  if (TypeSourceInfo *TSI = D->getFriendType()) {
613    unsigned NumTPLists = D->getFriendTypeNumTemplateParameterLists();
614    for (unsigned i = 0; i < NumTPLists; ++i)
615      PrintTemplateParameters(D->getFriendTypeTemplateParameterList(i));
616    Out << "friend ";
617    Out << " " << TSI->getType().getAsString(Policy);
618  }
619  else if (FunctionDecl *FD =
620      dyn_cast<FunctionDecl>(D->getFriendDecl())) {
621    Out << "friend ";
622    VisitFunctionDecl(FD);
623  }
624  else if (FunctionTemplateDecl *FTD =
625           dyn_cast<FunctionTemplateDecl>(D->getFriendDecl())) {
626    Out << "friend ";
627    VisitFunctionTemplateDecl(FTD);
628  }
629  else if (ClassTemplateDecl *CTD =
630           dyn_cast<ClassTemplateDecl>(D->getFriendDecl())) {
631    Out << "friend ";
632    VisitRedeclarableTemplateDecl(CTD);
633  }
634}
635
636void DeclPrinter::VisitFieldDecl(FieldDecl *D) {
637  if (!Policy.SuppressSpecifiers && D->isMutable())
638    Out << "mutable ";
639  if (!Policy.SuppressSpecifiers && D->isModulePrivate())
640    Out << "__module_private__ ";
641
642  Out << D->getASTContext().getUnqualifiedObjCPointerType(D->getType()).
643            stream(Policy, D->getName());
644
645  if (D->isBitField()) {
646    Out << " : ";
647    D->getBitWidth()->printPretty(Out, nullptr, Policy, Indentation);
648  }
649
650  Expr *Init = D->getInClassInitializer();
651  if (!Policy.SuppressInitializers && Init) {
652    if (D->getInClassInitStyle() == ICIS_ListInit)
653      Out << " ";
654    else
655      Out << " = ";
656    Init->printPretty(Out, nullptr, Policy, Indentation);
657  }
658  prettyPrintAttributes(D);
659}
660
661void DeclPrinter::VisitLabelDecl(LabelDecl *D) {
662  Out << *D << ":";
663}
664
665void DeclPrinter::VisitVarDecl(VarDecl *D) {
666  if (!Policy.SuppressSpecifiers) {
667    StorageClass SC = D->getStorageClass();
668    if (SC != SC_None)
669      Out << VarDecl::getStorageClassSpecifierString(SC) << " ";
670
671    switch (D->getTSCSpec()) {
672    case TSCS_unspecified:
673      break;
674    case TSCS___thread:
675      Out << "__thread ";
676      break;
677    case TSCS__Thread_local:
678      Out << "_Thread_local ";
679      break;
680    case TSCS_thread_local:
681      Out << "thread_local ";
682      break;
683    }
684
685    if (D->isModulePrivate())
686      Out << "__module_private__ ";
687  }
688
689  QualType T = D->getTypeSourceInfo()
690    ? D->getTypeSourceInfo()->getType()
691    : D->getASTContext().getUnqualifiedObjCPointerType(D->getType());
692  printDeclType(T, D->getName());
693  Expr *Init = D->getInit();
694  if (!Policy.SuppressInitializers && Init) {
695    bool ImplicitInit = false;
696    if (CXXConstructExpr *Construct =
697            dyn_cast<CXXConstructExpr>(Init->IgnoreImplicit())) {
698      if (D->getInitStyle() == VarDecl::CallInit &&
699          !Construct->isListInitialization()) {
700        ImplicitInit = Construct->getNumArgs() == 0 ||
701          Construct->getArg(0)->isDefaultArgument();
702      }
703    }
704    if (!ImplicitInit) {
705      if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init))
706        Out << "(";
707      else if (D->getInitStyle() == VarDecl::CInit) {
708        Out << " = ";
709      }
710      Init->printPretty(Out, nullptr, Policy, Indentation);
711      if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init))
712        Out << ")";
713    }
714  }
715  prettyPrintAttributes(D);
716}
717
718void DeclPrinter::VisitParmVarDecl(ParmVarDecl *D) {
719  VisitVarDecl(D);
720}
721
722void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
723  Out << "__asm (";
724  D->getAsmString()->printPretty(Out, nullptr, Policy, Indentation);
725  Out << ")";
726}
727
728void DeclPrinter::VisitImportDecl(ImportDecl *D) {
729  Out << "@import " << D->getImportedModule()->getFullModuleName()
730      << ";\n";
731}
732
733void DeclPrinter::VisitStaticAssertDecl(StaticAssertDecl *D) {
734  Out << "static_assert(";
735  D->getAssertExpr()->printPretty(Out, nullptr, Policy, Indentation);
736  Out << ", ";
737  D->getMessage()->printPretty(Out, nullptr, Policy, Indentation);
738  Out << ")";
739}
740
741//----------------------------------------------------------------------------
742// C++ declarations
743//----------------------------------------------------------------------------
744void DeclPrinter::VisitNamespaceDecl(NamespaceDecl *D) {
745  if (D->isInline())
746    Out << "inline ";
747  Out << "namespace " << *D << " {\n";
748  VisitDeclContext(D);
749  Indent() << "}";
750}
751
752void DeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
753  Out << "using namespace ";
754  if (D->getQualifier())
755    D->getQualifier()->print(Out, Policy);
756  Out << *D->getNominatedNamespaceAsWritten();
757}
758
759void DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
760  Out << "namespace " << *D << " = ";
761  if (D->getQualifier())
762    D->getQualifier()->print(Out, Policy);
763  Out << *D->getAliasedNamespace();
764}
765
766void DeclPrinter::VisitEmptyDecl(EmptyDecl *D) {
767  prettyPrintAttributes(D);
768}
769
770void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
771  if (!Policy.SuppressSpecifiers && D->isModulePrivate())
772    Out << "__module_private__ ";
773  Out << D->getKindName();
774
775  prettyPrintAttributes(D);
776
777  if (D->getIdentifier())
778    Out << ' ' << *D;
779
780  if (D->isCompleteDefinition()) {
781    // Print the base classes
782    if (D->getNumBases()) {
783      Out << " : ";
784      for (CXXRecordDecl::base_class_iterator Base = D->bases_begin(),
785             BaseEnd = D->bases_end(); Base != BaseEnd; ++Base) {
786        if (Base != D->bases_begin())
787          Out << ", ";
788
789        if (Base->isVirtual())
790          Out << "virtual ";
791
792        AccessSpecifier AS = Base->getAccessSpecifierAsWritten();
793        if (AS != AS_none) {
794          Print(AS);
795          Out << " ";
796        }
797        Out << Base->getType().getAsString(Policy);
798
799        if (Base->isPackExpansion())
800          Out << "...";
801      }
802    }
803
804    // Print the class definition
805    // FIXME: Doesn't print access specifiers, e.g., "public:"
806    Out << " {\n";
807    VisitDeclContext(D);
808    Indent() << "}";
809  }
810}
811
812void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
813  const char *l;
814  if (D->getLanguage() == LinkageSpecDecl::lang_c)
815    l = "C";
816  else {
817    assert(D->getLanguage() == LinkageSpecDecl::lang_cxx &&
818           "unknown language in linkage specification");
819    l = "C++";
820  }
821
822  Out << "extern \"" << l << "\" ";
823  if (D->hasBraces()) {
824    Out << "{\n";
825    VisitDeclContext(D);
826    Indent() << "}";
827  } else
828    Visit(*D->decls_begin());
829}
830
831void DeclPrinter::PrintTemplateParameters(const TemplateParameterList *Params,
832                                          const TemplateArgumentList *Args) {
833  assert(Params);
834  assert(!Args || Params->size() == Args->size());
835
836  Out << "template <";
837
838  for (unsigned i = 0, e = Params->size(); i != e; ++i) {
839    if (i != 0)
840      Out << ", ";
841
842    const Decl *Param = Params->getParam(i);
843    if (const TemplateTypeParmDecl *TTP =
844          dyn_cast<TemplateTypeParmDecl>(Param)) {
845
846      if (TTP->wasDeclaredWithTypename())
847        Out << "typename ";
848      else
849        Out << "class ";
850
851      if (TTP->isParameterPack())
852        Out << "...";
853
854      Out << *TTP;
855
856      if (Args) {
857        Out << " = ";
858        Args->get(i).print(Policy, Out);
859      } else if (TTP->hasDefaultArgument()) {
860        Out << " = ";
861        Out << TTP->getDefaultArgument().getAsString(Policy);
862      };
863    } else if (const NonTypeTemplateParmDecl *NTTP =
864                 dyn_cast<NonTypeTemplateParmDecl>(Param)) {
865      StringRef Name;
866      if (IdentifierInfo *II = NTTP->getIdentifier())
867        Name = II->getName();
868      printDeclType(NTTP->getType(), Name, NTTP->isParameterPack());
869
870      if (Args) {
871        Out << " = ";
872        Args->get(i).print(Policy, Out);
873      } else if (NTTP->hasDefaultArgument()) {
874        Out << " = ";
875        NTTP->getDefaultArgument()->printPretty(Out, nullptr, Policy,
876                                                Indentation);
877      }
878    } else if (const TemplateTemplateParmDecl *TTPD =
879                 dyn_cast<TemplateTemplateParmDecl>(Param)) {
880      VisitTemplateDecl(TTPD);
881      // FIXME: print the default argument, if present.
882    }
883  }
884
885  Out << "> ";
886}
887
888void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
889  PrintTemplateParameters(D->getTemplateParameters());
890
891  if (const TemplateTemplateParmDecl *TTP =
892        dyn_cast<TemplateTemplateParmDecl>(D)) {
893    Out << "class ";
894    if (TTP->isParameterPack())
895      Out << "...";
896    Out << D->getName();
897  } else {
898    Visit(D->getTemplatedDecl());
899  }
900}
901
902void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
903  if (PrintInstantiation) {
904    TemplateParameterList *Params = D->getTemplateParameters();
905    for (auto *I : D->specializations()) {
906      PrintTemplateParameters(Params, I->getTemplateSpecializationArgs());
907      Visit(I);
908    }
909  }
910
911  return VisitRedeclarableTemplateDecl(D);
912}
913
914void DeclPrinter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
915  if (PrintInstantiation) {
916    TemplateParameterList *Params = D->getTemplateParameters();
917    for (auto *I : D->specializations()) {
918      PrintTemplateParameters(Params, &I->getTemplateArgs());
919      Visit(I);
920      Out << '\n';
921    }
922  }
923
924  return VisitRedeclarableTemplateDecl(D);
925}
926
927//----------------------------------------------------------------------------
928// Objective-C declarations
929//----------------------------------------------------------------------------
930
931void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) {
932  if (OMD->isInstanceMethod())
933    Out << "- ";
934  else
935    Out << "+ ";
936  if (!OMD->getReturnType().isNull())
937    Out << '(' << OMD->getASTContext()
938                      .getUnqualifiedObjCPointerType(OMD->getReturnType())
939                      .getAsString(Policy) << ")";
940
941  std::string name = OMD->getSelector().getAsString();
942  std::string::size_type pos, lastPos = 0;
943  for (const auto *PI : OMD->params()) {
944    // FIXME: selector is missing here!
945    pos = name.find_first_of(':', lastPos);
946    Out << " " << name.substr(lastPos, pos - lastPos);
947    Out << ":(" << PI->getASTContext().getUnqualifiedObjCPointerType(PI->getType()).
948                      getAsString(Policy) << ')' << *PI;
949    lastPos = pos + 1;
950  }
951
952  if (OMD->param_begin() == OMD->param_end())
953    Out << " " << name;
954
955  if (OMD->isVariadic())
956      Out << ", ...";
957
958  prettyPrintAttributes(OMD);
959
960  if (OMD->getBody() && !Policy.TerseOutput) {
961    Out << ' ';
962    OMD->getBody()->printPretty(Out, nullptr, Policy);
963  }
964  else if (Policy.PolishForDeclaration)
965    Out << ';';
966}
967
968void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) {
969  std::string I = OID->getNameAsString();
970  ObjCInterfaceDecl *SID = OID->getSuperClass();
971
972  bool eolnOut = false;
973  if (SID)
974    Out << "@implementation " << I << " : " << *SID;
975  else
976    Out << "@implementation " << I;
977
978  if (OID->ivar_size() > 0) {
979    Out << "{\n";
980    eolnOut = true;
981    Indentation += Policy.Indentation;
982    for (const auto *I : OID->ivars()) {
983      Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
984                    getAsString(Policy) << ' ' << *I << ";\n";
985    }
986    Indentation -= Policy.Indentation;
987    Out << "}\n";
988  }
989  else if (SID || (OID->decls_begin() != OID->decls_end())) {
990    Out << "\n";
991    eolnOut = true;
992  }
993  VisitDeclContext(OID, false);
994  if (!eolnOut)
995    Out << "\n";
996  Out << "@end";
997}
998
999void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
1000  std::string I = OID->getNameAsString();
1001  ObjCInterfaceDecl *SID = OID->getSuperClass();
1002
1003  if (!OID->isThisDeclarationADefinition()) {
1004    Out << "@class " << I << ";";
1005    return;
1006  }
1007  bool eolnOut = false;
1008  if (SID)
1009    Out << "@interface " << I << " : " << *SID;
1010  else
1011    Out << "@interface " << I;
1012
1013  // Protocols?
1014  const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();
1015  if (!Protocols.empty()) {
1016    for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
1017         E = Protocols.end(); I != E; ++I)
1018      Out << (I == Protocols.begin() ? '<' : ',') << **I;
1019    Out << "> ";
1020  }
1021
1022  if (OID->ivar_size() > 0) {
1023    Out << "{\n";
1024    eolnOut = true;
1025    Indentation += Policy.Indentation;
1026    for (const auto *I : OID->ivars()) {
1027      Indent() << I->getASTContext()
1028                      .getUnqualifiedObjCPointerType(I->getType())
1029                      .getAsString(Policy) << ' ' << *I << ";\n";
1030    }
1031    Indentation -= Policy.Indentation;
1032    Out << "}\n";
1033  }
1034  else if (SID || (OID->decls_begin() != OID->decls_end())) {
1035    Out << "\n";
1036    eolnOut = true;
1037  }
1038
1039  VisitDeclContext(OID, false);
1040  if (!eolnOut)
1041    Out << "\n";
1042  Out << "@end";
1043  // FIXME: implement the rest...
1044}
1045
1046void DeclPrinter::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1047  if (!PID->isThisDeclarationADefinition()) {
1048    Out << "@protocol " << *PID << ";\n";
1049    return;
1050  }
1051  // Protocols?
1052  const ObjCList<ObjCProtocolDecl> &Protocols = PID->getReferencedProtocols();
1053  if (!Protocols.empty()) {
1054    Out << "@protocol " << *PID;
1055    for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
1056         E = Protocols.end(); I != E; ++I)
1057      Out << (I == Protocols.begin() ? '<' : ',') << **I;
1058    Out << ">\n";
1059  } else
1060    Out << "@protocol " << *PID << '\n';
1061  VisitDeclContext(PID, false);
1062  Out << "@end";
1063}
1064
1065void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) {
1066  Out << "@implementation " << *PID->getClassInterface() << '(' << *PID <<")\n";
1067
1068  VisitDeclContext(PID, false);
1069  Out << "@end";
1070  // FIXME: implement the rest...
1071}
1072
1073void DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) {
1074  Out << "@interface " << *PID->getClassInterface() << '(' << *PID << ")\n";
1075  if (PID->ivar_size() > 0) {
1076    Out << "{\n";
1077    Indentation += Policy.Indentation;
1078    for (const auto *I : PID->ivars())
1079      Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
1080                    getAsString(Policy) << ' ' << *I << ";\n";
1081    Indentation -= Policy.Indentation;
1082    Out << "}\n";
1083  }
1084
1085  VisitDeclContext(PID, false);
1086  Out << "@end";
1087
1088  // FIXME: implement the rest...
1089}
1090
1091void DeclPrinter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID) {
1092  Out << "@compatibility_alias " << *AID
1093      << ' ' << *AID->getClassInterface() << ";\n";
1094}
1095
1096/// PrintObjCPropertyDecl - print a property declaration.
1097///
1098void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
1099  if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Required)
1100    Out << "@required\n";
1101  else if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Optional)
1102    Out << "@optional\n";
1103
1104  Out << "@property";
1105  if (PDecl->getPropertyAttributes() != ObjCPropertyDecl::OBJC_PR_noattr) {
1106    bool first = true;
1107    Out << " (";
1108    if (PDecl->getPropertyAttributes() &
1109        ObjCPropertyDecl::OBJC_PR_readonly) {
1110      Out << (first ? ' ' : ',') << "readonly";
1111      first = false;
1112    }
1113
1114    if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) {
1115      Out << (first ? ' ' : ',') << "getter = ";
1116      PDecl->getGetterName().print(Out);
1117      first = false;
1118    }
1119    if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) {
1120      Out << (first ? ' ' : ',') << "setter = ";
1121      PDecl->getSetterName().print(Out);
1122      first = false;
1123    }
1124
1125    if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_assign) {
1126      Out << (first ? ' ' : ',') << "assign";
1127      first = false;
1128    }
1129
1130    if (PDecl->getPropertyAttributes() &
1131        ObjCPropertyDecl::OBJC_PR_readwrite) {
1132      Out << (first ? ' ' : ',') << "readwrite";
1133      first = false;
1134    }
1135
1136    if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) {
1137      Out << (first ? ' ' : ',') << "retain";
1138      first = false;
1139    }
1140
1141    if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_strong) {
1142      Out << (first ? ' ' : ',') << "strong";
1143      first = false;
1144    }
1145
1146    if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) {
1147      Out << (first ? ' ' : ',') << "copy";
1148      first = false;
1149    }
1150
1151    if (PDecl->getPropertyAttributes() &
1152        ObjCPropertyDecl::OBJC_PR_nonatomic) {
1153      Out << (first ? ' ' : ',') << "nonatomic";
1154      first = false;
1155    }
1156    if (PDecl->getPropertyAttributes() &
1157        ObjCPropertyDecl::OBJC_PR_atomic) {
1158      Out << (first ? ' ' : ',') << "atomic";
1159      first = false;
1160    }
1161
1162    (void) first; // Silence dead store warning due to idiomatic code.
1163    Out << " )";
1164  }
1165  Out << ' ' << PDecl->getASTContext().getUnqualifiedObjCPointerType(PDecl->getType()).
1166                  getAsString(Policy) << ' ' << *PDecl;
1167  if (Policy.PolishForDeclaration)
1168    Out << ';';
1169}
1170
1171void DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) {
1172  if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
1173    Out << "@synthesize ";
1174  else
1175    Out << "@dynamic ";
1176  Out << *PID->getPropertyDecl();
1177  if (PID->getPropertyIvarDecl())
1178    Out << '=' << *PID->getPropertyIvarDecl();
1179}
1180
1181void DeclPrinter::VisitUsingDecl(UsingDecl *D) {
1182  if (!D->isAccessDeclaration())
1183    Out << "using ";
1184  if (D->hasTypename())
1185    Out << "typename ";
1186  D->getQualifier()->print(Out, Policy);
1187  Out << *D;
1188}
1189
1190void
1191DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
1192  Out << "using typename ";
1193  D->getQualifier()->print(Out, Policy);
1194  Out << D->getDeclName();
1195}
1196
1197void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1198  if (!D->isAccessDeclaration())
1199    Out << "using ";
1200  D->getQualifier()->print(Out, Policy);
1201  Out << D->getName();
1202}
1203
1204void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) {
1205  // ignore
1206}
1207
1208void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
1209  Out << "#pragma omp threadprivate";
1210  if (!D->varlist_empty()) {
1211    for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(),
1212                                                E = D->varlist_end();
1213                                                I != E; ++I) {
1214      Out << (I == D->varlist_begin() ? '(' : ',');
1215      NamedDecl *ND = cast<NamedDecl>(cast<DeclRefExpr>(*I)->getDecl());
1216      ND->printQualifiedName(Out);
1217    }
1218    Out << ")";
1219  }
1220}
1221
1222