xref: /freebsd/contrib/llvm-project/clang/lib/AST/DeclPrinter.cpp (revision 0fca6ea1d4eea4c934cfff25ac9ee8ad6fe95583)
1  //===--- DeclPrinter.cpp - Printing implementation for Decl ASTs ----------===//
2  //
3  // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4  // See https://llvm.org/LICENSE.txt for license information.
5  // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6  //
7  //===----------------------------------------------------------------------===//
8  //
9  // This file implements the Decl::print method, which pretty prints the
10  // AST back out to C/Objective-C/C++/Objective-C++ code.
11  //
12  //===----------------------------------------------------------------------===//
13  #include "clang/AST/ASTContext.h"
14  #include "clang/AST/Attr.h"
15  #include "clang/AST/Decl.h"
16  #include "clang/AST/DeclCXX.h"
17  #include "clang/AST/DeclObjC.h"
18  #include "clang/AST/DeclTemplate.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 "clang/Basic/SourceManager.h"
25  #include "llvm/Support/raw_ostream.h"
26  using namespace clang;
27  
28  namespace {
29    class DeclPrinter : public DeclVisitor<DeclPrinter> {
30      raw_ostream &Out;
31      PrintingPolicy Policy;
32      const ASTContext &Context;
33      unsigned Indentation;
34      bool PrintInstantiation;
35  
Indent()36      raw_ostream& Indent() { return Indent(Indentation); }
37      raw_ostream& Indent(unsigned Indentation);
38      void ProcessDeclGroup(SmallVectorImpl<Decl*>& Decls);
39  
40      void Print(AccessSpecifier AS);
41      void PrintConstructorInitializers(CXXConstructorDecl *CDecl,
42                                        std::string &Proto);
43  
44      /// Print an Objective-C method type in parentheses.
45      ///
46      /// \param Quals The Objective-C declaration qualifiers.
47      /// \param T The type to print.
48      void PrintObjCMethodType(ASTContext &Ctx, Decl::ObjCDeclQualifier Quals,
49                               QualType T);
50  
51      void PrintObjCTypeParams(ObjCTypeParamList *Params);
52  
53    public:
DeclPrinter(raw_ostream & Out,const PrintingPolicy & Policy,const ASTContext & Context,unsigned Indentation=0,bool PrintInstantiation=false)54      DeclPrinter(raw_ostream &Out, const PrintingPolicy &Policy,
55                  const ASTContext &Context, unsigned Indentation = 0,
56                  bool PrintInstantiation = false)
57          : Out(Out), Policy(Policy), Context(Context), Indentation(Indentation),
58            PrintInstantiation(PrintInstantiation) {}
59  
60      void VisitDeclContext(DeclContext *DC, bool Indent = true);
61  
62      void VisitTranslationUnitDecl(TranslationUnitDecl *D);
63      void VisitTypedefDecl(TypedefDecl *D);
64      void VisitTypeAliasDecl(TypeAliasDecl *D);
65      void VisitEnumDecl(EnumDecl *D);
66      void VisitRecordDecl(RecordDecl *D);
67      void VisitEnumConstantDecl(EnumConstantDecl *D);
68      void VisitEmptyDecl(EmptyDecl *D);
69      void VisitFunctionDecl(FunctionDecl *D);
70      void VisitFriendDecl(FriendDecl *D);
71      void VisitFieldDecl(FieldDecl *D);
72      void VisitVarDecl(VarDecl *D);
73      void VisitLabelDecl(LabelDecl *D);
74      void VisitParmVarDecl(ParmVarDecl *D);
75      void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
76      void VisitTopLevelStmtDecl(TopLevelStmtDecl *D);
77      void VisitImportDecl(ImportDecl *D);
78      void VisitStaticAssertDecl(StaticAssertDecl *D);
79      void VisitNamespaceDecl(NamespaceDecl *D);
80      void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
81      void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
82      void VisitCXXRecordDecl(CXXRecordDecl *D);
83      void VisitLinkageSpecDecl(LinkageSpecDecl *D);
84      void VisitTemplateDecl(const TemplateDecl *D);
85      void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
86      void VisitClassTemplateDecl(ClassTemplateDecl *D);
87      void VisitClassTemplateSpecializationDecl(
88                                              ClassTemplateSpecializationDecl *D);
89      void VisitClassTemplatePartialSpecializationDecl(
90                                       ClassTemplatePartialSpecializationDecl *D);
91      void VisitObjCMethodDecl(ObjCMethodDecl *D);
92      void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
93      void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
94      void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
95      void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
96      void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
97      void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
98      void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
99      void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
100      void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
101      void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
102      void VisitUsingDecl(UsingDecl *D);
103      void VisitUsingEnumDecl(UsingEnumDecl *D);
104      void VisitUsingShadowDecl(UsingShadowDecl *D);
105      void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
106      void VisitOMPAllocateDecl(OMPAllocateDecl *D);
107      void VisitOMPRequiresDecl(OMPRequiresDecl *D);
108      void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
109      void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D);
110      void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
111      void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *TTP);
112      void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *NTTP);
113      void VisitHLSLBufferDecl(HLSLBufferDecl *D);
114  
115      void printTemplateParameters(const TemplateParameterList *Params,
116                                   bool OmitTemplateKW = false);
117      void printTemplateArguments(llvm::ArrayRef<TemplateArgument> Args,
118                                  const TemplateParameterList *Params);
119      void printTemplateArguments(llvm::ArrayRef<TemplateArgumentLoc> Args,
120                                  const TemplateParameterList *Params);
121      enum class AttrPosAsWritten { Default = 0, Left, Right };
122      bool
123      prettyPrintAttributes(const Decl *D,
124                            AttrPosAsWritten Pos = AttrPosAsWritten::Default);
125      void prettyPrintPragmas(Decl *D);
126      void printDeclType(QualType T, StringRef DeclName, bool Pack = false);
127    };
128  }
129  
print(raw_ostream & Out,unsigned Indentation,bool PrintInstantiation) const130  void Decl::print(raw_ostream &Out, unsigned Indentation,
131                   bool PrintInstantiation) const {
132    print(Out, getASTContext().getPrintingPolicy(), Indentation, PrintInstantiation);
133  }
134  
print(raw_ostream & Out,const PrintingPolicy & Policy,unsigned Indentation,bool PrintInstantiation) const135  void Decl::print(raw_ostream &Out, const PrintingPolicy &Policy,
136                   unsigned Indentation, bool PrintInstantiation) const {
137    DeclPrinter Printer(Out, Policy, getASTContext(), Indentation,
138                        PrintInstantiation);
139    Printer.Visit(const_cast<Decl*>(this));
140  }
141  
print(raw_ostream & Out,const ASTContext & Context,bool OmitTemplateKW) const142  void TemplateParameterList::print(raw_ostream &Out, const ASTContext &Context,
143                                    bool OmitTemplateKW) const {
144    print(Out, Context, Context.getPrintingPolicy(), OmitTemplateKW);
145  }
146  
print(raw_ostream & Out,const ASTContext & Context,const PrintingPolicy & Policy,bool OmitTemplateKW) const147  void TemplateParameterList::print(raw_ostream &Out, const ASTContext &Context,
148                                    const PrintingPolicy &Policy,
149                                    bool OmitTemplateKW) const {
150    DeclPrinter Printer(Out, Policy, Context);
151    Printer.printTemplateParameters(this, OmitTemplateKW);
152  }
153  
GetBaseType(QualType T)154  static QualType GetBaseType(QualType T) {
155    // FIXME: This should be on the Type class!
156    QualType BaseType = T;
157    while (!BaseType->isSpecifierType()) {
158      if (const PointerType *PTy = BaseType->getAs<PointerType>())
159        BaseType = PTy->getPointeeType();
160      else if (const ObjCObjectPointerType *OPT =
161                   BaseType->getAs<ObjCObjectPointerType>())
162        BaseType = OPT->getPointeeType();
163      else if (const BlockPointerType *BPy = BaseType->getAs<BlockPointerType>())
164        BaseType = BPy->getPointeeType();
165      else if (const ArrayType *ATy = dyn_cast<ArrayType>(BaseType))
166        BaseType = ATy->getElementType();
167      else if (const FunctionType *FTy = BaseType->getAs<FunctionType>())
168        BaseType = FTy->getReturnType();
169      else if (const VectorType *VTy = BaseType->getAs<VectorType>())
170        BaseType = VTy->getElementType();
171      else if (const ReferenceType *RTy = BaseType->getAs<ReferenceType>())
172        BaseType = RTy->getPointeeType();
173      else if (const AutoType *ATy = BaseType->getAs<AutoType>())
174        BaseType = ATy->getDeducedType();
175      else if (const ParenType *PTy = BaseType->getAs<ParenType>())
176        BaseType = PTy->desugar();
177      else
178        // This must be a syntax error.
179        break;
180    }
181    return BaseType;
182  }
183  
getDeclType(Decl * D)184  static QualType getDeclType(Decl* D) {
185    if (TypedefNameDecl* TDD = dyn_cast<TypedefNameDecl>(D))
186      return TDD->getUnderlyingType();
187    if (ValueDecl* VD = dyn_cast<ValueDecl>(D))
188      return VD->getType();
189    return QualType();
190  }
191  
printGroup(Decl ** Begin,unsigned NumDecls,raw_ostream & Out,const PrintingPolicy & Policy,unsigned Indentation)192  void Decl::printGroup(Decl** Begin, unsigned NumDecls,
193                        raw_ostream &Out, const PrintingPolicy &Policy,
194                        unsigned Indentation) {
195    if (NumDecls == 1) {
196      (*Begin)->print(Out, Policy, Indentation);
197      return;
198    }
199  
200    Decl** End = Begin + NumDecls;
201    TagDecl* TD = dyn_cast<TagDecl>(*Begin);
202    if (TD)
203      ++Begin;
204  
205    PrintingPolicy SubPolicy(Policy);
206  
207    bool isFirst = true;
208    for ( ; Begin != End; ++Begin) {
209      if (isFirst) {
210        if(TD)
211          SubPolicy.IncludeTagDefinition = true;
212        SubPolicy.SuppressSpecifiers = false;
213        isFirst = false;
214      } else {
215        if (!isFirst) Out << ", ";
216        SubPolicy.IncludeTagDefinition = false;
217        SubPolicy.SuppressSpecifiers = true;
218      }
219  
220      (*Begin)->print(Out, SubPolicy, Indentation);
221    }
222  }
223  
dumpDeclContext() const224  LLVM_DUMP_METHOD void DeclContext::dumpDeclContext() const {
225    // Get the translation unit
226    const DeclContext *DC = this;
227    while (!DC->isTranslationUnit())
228      DC = DC->getParent();
229  
230    ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
231    DeclPrinter Printer(llvm::errs(), Ctx.getPrintingPolicy(), Ctx, 0);
232    Printer.VisitDeclContext(const_cast<DeclContext *>(this), /*Indent=*/false);
233  }
234  
Indent(unsigned Indentation)235  raw_ostream& DeclPrinter::Indent(unsigned Indentation) {
236    for (unsigned i = 0; i != Indentation; ++i)
237      Out << "  ";
238    return Out;
239  }
240  
getPosAsWritten(const Attr * A,const Decl * D)241  static DeclPrinter::AttrPosAsWritten getPosAsWritten(const Attr *A,
242                                                       const Decl *D) {
243    SourceLocation ALoc = A->getLoc();
244    SourceLocation DLoc = D->getLocation();
245    const ASTContext &C = D->getASTContext();
246    if (ALoc.isInvalid() || DLoc.isInvalid())
247      return DeclPrinter::AttrPosAsWritten::Left;
248  
249    if (C.getSourceManager().isBeforeInTranslationUnit(ALoc, DLoc))
250      return DeclPrinter::AttrPosAsWritten::Left;
251  
252    return DeclPrinter::AttrPosAsWritten::Right;
253  }
254  
255  // returns true if an attribute was printed.
prettyPrintAttributes(const Decl * D,AttrPosAsWritten Pos)256  bool DeclPrinter::prettyPrintAttributes(const Decl *D,
257                                          AttrPosAsWritten Pos /*=Default*/) {
258    bool hasPrinted = false;
259  
260    if (D->hasAttrs()) {
261      const AttrVec &Attrs = D->getAttrs();
262      for (auto *A : Attrs) {
263        if (A->isInherited() || A->isImplicit())
264          continue;
265        // Print out the keyword attributes, they aren't regular attributes.
266        if (Policy.PolishForDeclaration && !A->isKeywordAttribute())
267          continue;
268        switch (A->getKind()) {
269  #define ATTR(X)
270  #define PRAGMA_SPELLING_ATTR(X) case attr::X:
271  #include "clang/Basic/AttrList.inc"
272          break;
273        default:
274          AttrPosAsWritten APos = getPosAsWritten(A, D);
275          assert(APos != AttrPosAsWritten::Default &&
276                 "Default not a valid for an attribute location");
277          if (Pos == AttrPosAsWritten::Default || Pos == APos) {
278            if (Pos != AttrPosAsWritten::Left)
279              Out << ' ';
280            A->printPretty(Out, Policy);
281            hasPrinted = true;
282            if (Pos == AttrPosAsWritten::Left)
283              Out << ' ';
284          }
285          break;
286        }
287      }
288    }
289    return hasPrinted;
290  }
291  
prettyPrintPragmas(Decl * D)292  void DeclPrinter::prettyPrintPragmas(Decl *D) {
293    if (Policy.PolishForDeclaration)
294      return;
295  
296    if (D->hasAttrs()) {
297      AttrVec &Attrs = D->getAttrs();
298      for (auto *A : Attrs) {
299        switch (A->getKind()) {
300  #define ATTR(X)
301  #define PRAGMA_SPELLING_ATTR(X) case attr::X:
302  #include "clang/Basic/AttrList.inc"
303          A->printPretty(Out, Policy);
304          Indent();
305          break;
306        default:
307          break;
308        }
309      }
310    }
311  }
312  
printDeclType(QualType T,StringRef DeclName,bool Pack)313  void DeclPrinter::printDeclType(QualType T, StringRef DeclName, bool Pack) {
314    // Normally, a PackExpansionType is written as T[3]... (for instance, as a
315    // template argument), but if it is the type of a declaration, the ellipsis
316    // is placed before the name being declared.
317    if (auto *PET = T->getAs<PackExpansionType>()) {
318      Pack = true;
319      T = PET->getPattern();
320    }
321    T.print(Out, Policy, (Pack ? "..." : "") + DeclName, Indentation);
322  }
323  
ProcessDeclGroup(SmallVectorImpl<Decl * > & Decls)324  void DeclPrinter::ProcessDeclGroup(SmallVectorImpl<Decl*>& Decls) {
325    this->Indent();
326    Decl::printGroup(Decls.data(), Decls.size(), Out, Policy, Indentation);
327    Out << ";\n";
328    Decls.clear();
329  
330  }
331  
Print(AccessSpecifier AS)332  void DeclPrinter::Print(AccessSpecifier AS) {
333    const auto AccessSpelling = getAccessSpelling(AS);
334    if (AccessSpelling.empty())
335      llvm_unreachable("No access specifier!");
336    Out << AccessSpelling;
337  }
338  
PrintConstructorInitializers(CXXConstructorDecl * CDecl,std::string & Proto)339  void DeclPrinter::PrintConstructorInitializers(CXXConstructorDecl *CDecl,
340                                                 std::string &Proto) {
341    bool HasInitializerList = false;
342    for (const auto *BMInitializer : CDecl->inits()) {
343      if (BMInitializer->isInClassMemberInitializer())
344        continue;
345      if (!BMInitializer->isWritten())
346        continue;
347  
348      if (!HasInitializerList) {
349        Proto += " : ";
350        Out << Proto;
351        Proto.clear();
352        HasInitializerList = true;
353      } else
354        Out << ", ";
355  
356      if (BMInitializer->isAnyMemberInitializer()) {
357        FieldDecl *FD = BMInitializer->getAnyMember();
358        Out << *FD;
359      } else if (BMInitializer->isDelegatingInitializer()) {
360        Out << CDecl->getNameAsString();
361      } else {
362        Out << QualType(BMInitializer->getBaseClass(), 0).getAsString(Policy);
363      }
364  
365      if (Expr *Init = BMInitializer->getInit()) {
366        bool OutParens = !isa<InitListExpr>(Init);
367  
368        if (OutParens)
369          Out << "(";
370  
371        if (ExprWithCleanups *Tmp = dyn_cast<ExprWithCleanups>(Init))
372          Init = Tmp->getSubExpr();
373  
374        Init = Init->IgnoreParens();
375  
376        Expr *SimpleInit = nullptr;
377        Expr **Args = nullptr;
378        unsigned NumArgs = 0;
379        if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
380          Args = ParenList->getExprs();
381          NumArgs = ParenList->getNumExprs();
382        } else if (CXXConstructExpr *Construct =
383                       dyn_cast<CXXConstructExpr>(Init)) {
384          Args = Construct->getArgs();
385          NumArgs = Construct->getNumArgs();
386        } else
387          SimpleInit = Init;
388  
389        if (SimpleInit)
390          SimpleInit->printPretty(Out, nullptr, Policy, Indentation, "\n",
391                                  &Context);
392        else {
393          for (unsigned I = 0; I != NumArgs; ++I) {
394            assert(Args[I] != nullptr && "Expected non-null Expr");
395            if (isa<CXXDefaultArgExpr>(Args[I]))
396              break;
397  
398            if (I)
399              Out << ", ";
400            Args[I]->printPretty(Out, nullptr, Policy, Indentation, "\n",
401                                 &Context);
402          }
403        }
404  
405        if (OutParens)
406          Out << ")";
407      } else {
408        Out << "()";
409      }
410  
411      if (BMInitializer->isPackExpansion())
412        Out << "...";
413    }
414  }
415  
416  //----------------------------------------------------------------------------
417  // Common C declarations
418  //----------------------------------------------------------------------------
419  
VisitDeclContext(DeclContext * DC,bool Indent)420  void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
421    if (Policy.TerseOutput)
422      return;
423  
424    if (Indent)
425      Indentation += Policy.Indentation;
426  
427    SmallVector<Decl*, 2> Decls;
428    for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
429         D != DEnd; ++D) {
430  
431      // Don't print ObjCIvarDecls, as they are printed when visiting the
432      // containing ObjCInterfaceDecl.
433      if (isa<ObjCIvarDecl>(*D))
434        continue;
435  
436      // Skip over implicit declarations in pretty-printing mode.
437      if (D->isImplicit())
438        continue;
439  
440      // Don't print implicit specializations, as they are printed when visiting
441      // corresponding templates.
442      if (auto FD = dyn_cast<FunctionDecl>(*D))
443        if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation &&
444            !isa<ClassTemplateSpecializationDecl>(DC))
445          continue;
446  
447      // The next bits of code handle stuff like "struct {int x;} a,b"; we're
448      // forced to merge the declarations because there's no other way to
449      // refer to the struct in question.  When that struct is named instead, we
450      // also need to merge to avoid splitting off a stand-alone struct
451      // declaration that produces the warning ext_no_declarators in some
452      // contexts.
453      //
454      // This limited merging is safe without a bunch of other checks because it
455      // only merges declarations directly referring to the tag, not typedefs.
456      //
457      // Check whether the current declaration should be grouped with a previous
458      // non-free-standing tag declaration.
459      QualType CurDeclType = getDeclType(*D);
460      if (!Decls.empty() && !CurDeclType.isNull()) {
461        QualType BaseType = GetBaseType(CurDeclType);
462        if (!BaseType.isNull() && isa<ElaboratedType>(BaseType) &&
463            cast<ElaboratedType>(BaseType)->getOwnedTagDecl() == Decls[0]) {
464          Decls.push_back(*D);
465          continue;
466        }
467      }
468  
469      // If we have a merged group waiting to be handled, handle it now.
470      if (!Decls.empty())
471        ProcessDeclGroup(Decls);
472  
473      // If the current declaration is not a free standing declaration, save it
474      // so we can merge it with the subsequent declaration(s) using it.
475      if (isa<TagDecl>(*D) && !cast<TagDecl>(*D)->isFreeStanding()) {
476        Decls.push_back(*D);
477        continue;
478      }
479  
480      if (isa<AccessSpecDecl>(*D)) {
481        Indentation -= Policy.Indentation;
482        this->Indent();
483        Print(D->getAccess());
484        Out << ":\n";
485        Indentation += Policy.Indentation;
486        continue;
487      }
488  
489      this->Indent();
490      Visit(*D);
491  
492      // FIXME: Need to be able to tell the DeclPrinter when
493      const char *Terminator = nullptr;
494      if (isa<OMPThreadPrivateDecl>(*D) || isa<OMPDeclareReductionDecl>(*D) ||
495          isa<OMPDeclareMapperDecl>(*D) || isa<OMPRequiresDecl>(*D) ||
496          isa<OMPAllocateDecl>(*D))
497        Terminator = nullptr;
498      else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->hasBody())
499        Terminator = nullptr;
500      else if (auto FD = dyn_cast<FunctionDecl>(*D)) {
501        if (FD->doesThisDeclarationHaveABody() && !FD->isDefaulted())
502          Terminator = nullptr;
503        else
504          Terminator = ";";
505      } else if (auto TD = dyn_cast<FunctionTemplateDecl>(*D)) {
506        if (TD->getTemplatedDecl()->doesThisDeclarationHaveABody())
507          Terminator = nullptr;
508        else
509          Terminator = ";";
510      } else if (isa<NamespaceDecl, LinkageSpecDecl, ObjCImplementationDecl,
511                     ObjCInterfaceDecl, ObjCProtocolDecl, ObjCCategoryImplDecl,
512                     ObjCCategoryDecl, HLSLBufferDecl>(*D))
513        Terminator = nullptr;
514      else if (isa<EnumConstantDecl>(*D)) {
515        DeclContext::decl_iterator Next = D;
516        ++Next;
517        if (Next != DEnd)
518          Terminator = ",";
519      } else
520        Terminator = ";";
521  
522      if (Terminator)
523        Out << Terminator;
524      if (!Policy.TerseOutput &&
525          ((isa<FunctionDecl>(*D) &&
526            cast<FunctionDecl>(*D)->doesThisDeclarationHaveABody()) ||
527           (isa<FunctionTemplateDecl>(*D) &&
528            cast<FunctionTemplateDecl>(*D)->getTemplatedDecl()->doesThisDeclarationHaveABody())))
529        ; // StmtPrinter already added '\n' after CompoundStmt.
530      else
531        Out << "\n";
532  
533      // Declare target attribute is special one, natural spelling for the pragma
534      // assumes "ending" construct so print it here.
535      if (D->hasAttr<OMPDeclareTargetDeclAttr>())
536        Out << "#pragma omp end declare target\n";
537    }
538  
539    if (!Decls.empty())
540      ProcessDeclGroup(Decls);
541  
542    if (Indent)
543      Indentation -= Policy.Indentation;
544  }
545  
VisitTranslationUnitDecl(TranslationUnitDecl * D)546  void DeclPrinter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
547    VisitDeclContext(D, false);
548  }
549  
VisitTypedefDecl(TypedefDecl * D)550  void DeclPrinter::VisitTypedefDecl(TypedefDecl *D) {
551    if (!Policy.SuppressSpecifiers) {
552      Out << "typedef ";
553  
554      if (D->isModulePrivate())
555        Out << "__module_private__ ";
556    }
557    QualType Ty = D->getTypeSourceInfo()->getType();
558    Ty.print(Out, Policy, D->getName(), Indentation);
559    prettyPrintAttributes(D);
560  }
561  
VisitTypeAliasDecl(TypeAliasDecl * D)562  void DeclPrinter::VisitTypeAliasDecl(TypeAliasDecl *D) {
563    Out << "using " << *D;
564    prettyPrintAttributes(D);
565    Out << " = " << D->getTypeSourceInfo()->getType().getAsString(Policy);
566  }
567  
VisitEnumDecl(EnumDecl * D)568  void DeclPrinter::VisitEnumDecl(EnumDecl *D) {
569    if (!Policy.SuppressSpecifiers && D->isModulePrivate())
570      Out << "__module_private__ ";
571    Out << "enum";
572    if (D->isScoped()) {
573      if (D->isScopedUsingClassTag())
574        Out << " class";
575      else
576        Out << " struct";
577    }
578  
579    prettyPrintAttributes(D);
580  
581    if (D->getDeclName())
582      Out << ' ' << D->getDeclName();
583  
584    if (D->isFixed())
585      Out << " : " << D->getIntegerType().stream(Policy);
586  
587    if (D->isCompleteDefinition()) {
588      Out << " {\n";
589      VisitDeclContext(D);
590      Indent() << "}";
591    }
592  }
593  
VisitRecordDecl(RecordDecl * D)594  void DeclPrinter::VisitRecordDecl(RecordDecl *D) {
595    if (!Policy.SuppressSpecifiers && D->isModulePrivate())
596      Out << "__module_private__ ";
597    Out << D->getKindName();
598  
599    prettyPrintAttributes(D);
600  
601    if (D->getIdentifier())
602      Out << ' ' << *D;
603  
604    if (D->isCompleteDefinition()) {
605      Out << " {\n";
606      VisitDeclContext(D);
607      Indent() << "}";
608    }
609  }
610  
VisitEnumConstantDecl(EnumConstantDecl * D)611  void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) {
612    Out << *D;
613    prettyPrintAttributes(D);
614    if (Expr *Init = D->getInitExpr()) {
615      Out << " = ";
616      Init->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
617    }
618  }
619  
printExplicitSpecifier(ExplicitSpecifier ES,llvm::raw_ostream & Out,PrintingPolicy & Policy,unsigned Indentation,const ASTContext & Context)620  static void printExplicitSpecifier(ExplicitSpecifier ES, llvm::raw_ostream &Out,
621                                     PrintingPolicy &Policy, unsigned Indentation,
622                                     const ASTContext &Context) {
623    std::string Proto = "explicit";
624    llvm::raw_string_ostream EOut(Proto);
625    if (ES.getExpr()) {
626      EOut << "(";
627      ES.getExpr()->printPretty(EOut, nullptr, Policy, Indentation, "\n",
628                                &Context);
629      EOut << ")";
630    }
631    EOut << " ";
632    EOut.flush();
633    Out << Proto;
634  }
635  
MaybePrintTagKeywordIfSupressingScopes(PrintingPolicy & Policy,QualType T,llvm::raw_ostream & Out)636  static void MaybePrintTagKeywordIfSupressingScopes(PrintingPolicy &Policy,
637                                                     QualType T,
638                                                     llvm::raw_ostream &Out) {
639    StringRef prefix = T->isClassType()       ? "class "
640                       : T->isStructureType() ? "struct "
641                       : T->isUnionType()     ? "union "
642                                              : "";
643    Out << prefix;
644  }
645  
VisitFunctionDecl(FunctionDecl * D)646  void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
647    if (!D->getDescribedFunctionTemplate() &&
648        !D->isFunctionTemplateSpecialization()) {
649      prettyPrintPragmas(D);
650      prettyPrintAttributes(D, AttrPosAsWritten::Left);
651    }
652  
653    if (D->isFunctionTemplateSpecialization())
654      Out << "template<> ";
655    else if (!D->getDescribedFunctionTemplate()) {
656      for (unsigned I = 0, NumTemplateParams = D->getNumTemplateParameterLists();
657           I < NumTemplateParams; ++I)
658        printTemplateParameters(D->getTemplateParameterList(I));
659    }
660  
661    CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
662    CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
663    CXXDeductionGuideDecl *GuideDecl = dyn_cast<CXXDeductionGuideDecl>(D);
664    if (!Policy.SuppressSpecifiers) {
665      switch (D->getStorageClass()) {
666      case SC_None: break;
667      case SC_Extern: Out << "extern "; break;
668      case SC_Static: Out << "static "; break;
669      case SC_PrivateExtern: Out << "__private_extern__ "; break;
670      case SC_Auto: case SC_Register:
671        llvm_unreachable("invalid for functions");
672      }
673  
674      if (D->isInlineSpecified())  Out << "inline ";
675      if (D->isVirtualAsWritten()) Out << "virtual ";
676      if (D->isModulePrivate())    Out << "__module_private__ ";
677      if (D->isConstexprSpecified() && !D->isExplicitlyDefaulted())
678        Out << "constexpr ";
679      if (D->isConsteval())        Out << "consteval ";
680      else if (D->isImmediateFunction())
681        Out << "immediate ";
682      ExplicitSpecifier ExplicitSpec = ExplicitSpecifier::getFromDecl(D);
683      if (ExplicitSpec.isSpecified())
684        printExplicitSpecifier(ExplicitSpec, Out, Policy, Indentation, Context);
685    }
686  
687    PrintingPolicy SubPolicy(Policy);
688    SubPolicy.SuppressSpecifiers = false;
689    std::string Proto;
690  
691    if (Policy.FullyQualifiedName) {
692      Proto += D->getQualifiedNameAsString();
693    } else {
694      llvm::raw_string_ostream OS(Proto);
695      if (!Policy.SuppressScope) {
696        if (const NestedNameSpecifier *NS = D->getQualifier()) {
697          NS->print(OS, Policy);
698        }
699      }
700      D->getNameInfo().printName(OS, Policy);
701    }
702  
703    if (GuideDecl)
704      Proto = GuideDecl->getDeducedTemplate()->getDeclName().getAsString();
705    if (D->isFunctionTemplateSpecialization()) {
706      llvm::raw_string_ostream POut(Proto);
707      DeclPrinter TArgPrinter(POut, SubPolicy, Context, Indentation);
708      const auto *TArgAsWritten = D->getTemplateSpecializationArgsAsWritten();
709      if (TArgAsWritten && !Policy.PrintCanonicalTypes)
710        TArgPrinter.printTemplateArguments(TArgAsWritten->arguments(), nullptr);
711      else if (const TemplateArgumentList *TArgs =
712                   D->getTemplateSpecializationArgs())
713        TArgPrinter.printTemplateArguments(TArgs->asArray(), nullptr);
714    }
715  
716    QualType Ty = D->getType();
717    while (const ParenType *PT = dyn_cast<ParenType>(Ty)) {
718      Proto = '(' + Proto + ')';
719      Ty = PT->getInnerType();
720    }
721  
722    if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
723      const FunctionProtoType *FT = nullptr;
724      if (D->hasWrittenPrototype())
725        FT = dyn_cast<FunctionProtoType>(AFT);
726  
727      Proto += "(";
728      if (FT) {
729        llvm::raw_string_ostream POut(Proto);
730        DeclPrinter ParamPrinter(POut, SubPolicy, Context, Indentation);
731        for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
732          if (i) POut << ", ";
733          ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
734        }
735  
736        if (FT->isVariadic()) {
737          if (D->getNumParams()) POut << ", ";
738          POut << "...";
739        } else if (!D->getNumParams() && !Context.getLangOpts().CPlusPlus) {
740          // The function has a prototype, so it needs to retain the prototype
741          // in C.
742          POut << "void";
743        }
744      } else if (D->doesThisDeclarationHaveABody() && !D->hasPrototype()) {
745        for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
746          if (i)
747            Proto += ", ";
748          Proto += D->getParamDecl(i)->getNameAsString();
749        }
750      }
751  
752      Proto += ")";
753  
754      if (FT) {
755        if (FT->isConst())
756          Proto += " const";
757        if (FT->isVolatile())
758          Proto += " volatile";
759        if (FT->isRestrict())
760          Proto += " restrict";
761  
762        switch (FT->getRefQualifier()) {
763        case RQ_None:
764          break;
765        case RQ_LValue:
766          Proto += " &";
767          break;
768        case RQ_RValue:
769          Proto += " &&";
770          break;
771        }
772      }
773  
774      if (FT && FT->hasDynamicExceptionSpec()) {
775        Proto += " throw(";
776        if (FT->getExceptionSpecType() == EST_MSAny)
777          Proto += "...";
778        else
779          for (unsigned I = 0, N = FT->getNumExceptions(); I != N; ++I) {
780            if (I)
781              Proto += ", ";
782  
783            Proto += FT->getExceptionType(I).getAsString(SubPolicy);
784          }
785        Proto += ")";
786      } else if (FT && isNoexceptExceptionSpec(FT->getExceptionSpecType())) {
787        Proto += " noexcept";
788        if (isComputedNoexcept(FT->getExceptionSpecType())) {
789          Proto += "(";
790          llvm::raw_string_ostream EOut(Proto);
791          FT->getNoexceptExpr()->printPretty(EOut, nullptr, SubPolicy,
792                                             Indentation, "\n", &Context);
793          EOut.flush();
794          Proto += ")";
795        }
796      }
797  
798      if (CDecl) {
799        if (!Policy.TerseOutput)
800          PrintConstructorInitializers(CDecl, Proto);
801      } else if (!ConversionDecl && !isa<CXXDestructorDecl>(D)) {
802        if (FT && FT->hasTrailingReturn()) {
803          if (!GuideDecl)
804            Out << "auto ";
805          Out << Proto << " -> ";
806          Proto.clear();
807        }
808        if (!Policy.SuppressTagKeyword && Policy.SuppressScope &&
809            !Policy.SuppressUnwrittenScope)
810          MaybePrintTagKeywordIfSupressingScopes(Policy, AFT->getReturnType(),
811                                                 Out);
812        AFT->getReturnType().print(Out, Policy, Proto);
813        Proto.clear();
814      }
815      Out << Proto;
816  
817      if (Expr *TrailingRequiresClause = D->getTrailingRequiresClause()) {
818        Out << " requires ";
819        TrailingRequiresClause->printPretty(Out, nullptr, SubPolicy, Indentation,
820                                            "\n", &Context);
821      }
822    } else {
823      Ty.print(Out, Policy, Proto);
824    }
825  
826    prettyPrintAttributes(D, AttrPosAsWritten::Right);
827  
828    if (D->isPureVirtual())
829      Out << " = 0";
830    else if (D->isDeletedAsWritten()) {
831      Out << " = delete";
832      if (const StringLiteral *M = D->getDeletedMessage()) {
833        Out << "(";
834        M->outputString(Out);
835        Out << ")";
836      }
837    } else if (D->isExplicitlyDefaulted())
838      Out << " = default";
839    else if (D->doesThisDeclarationHaveABody()) {
840      if (!Policy.TerseOutput) {
841        if (!D->hasPrototype() && D->getNumParams()) {
842          // This is a K&R function definition, so we need to print the
843          // parameters.
844          Out << '\n';
845          DeclPrinter ParamPrinter(Out, SubPolicy, Context, Indentation);
846          Indentation += Policy.Indentation;
847          for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
848            Indent();
849            ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
850            Out << ";\n";
851          }
852          Indentation -= Policy.Indentation;
853        }
854  
855        if (D->getBody())
856          D->getBody()->printPrettyControlled(Out, nullptr, SubPolicy, Indentation, "\n",
857                                    &Context);
858      } else {
859        if (!Policy.TerseOutput && isa<CXXConstructorDecl>(*D))
860          Out << " {}";
861      }
862    }
863  }
864  
VisitFriendDecl(FriendDecl * D)865  void DeclPrinter::VisitFriendDecl(FriendDecl *D) {
866    if (TypeSourceInfo *TSI = D->getFriendType()) {
867      unsigned NumTPLists = D->getFriendTypeNumTemplateParameterLists();
868      for (unsigned i = 0; i < NumTPLists; ++i)
869        printTemplateParameters(D->getFriendTypeTemplateParameterList(i));
870      Out << "friend ";
871      Out << " " << TSI->getType().getAsString(Policy);
872    }
873    else if (FunctionDecl *FD =
874        dyn_cast<FunctionDecl>(D->getFriendDecl())) {
875      Out << "friend ";
876      VisitFunctionDecl(FD);
877    }
878    else if (FunctionTemplateDecl *FTD =
879             dyn_cast<FunctionTemplateDecl>(D->getFriendDecl())) {
880      Out << "friend ";
881      VisitFunctionTemplateDecl(FTD);
882    }
883    else if (ClassTemplateDecl *CTD =
884             dyn_cast<ClassTemplateDecl>(D->getFriendDecl())) {
885      Out << "friend ";
886      VisitRedeclarableTemplateDecl(CTD);
887    }
888  }
889  
VisitFieldDecl(FieldDecl * D)890  void DeclPrinter::VisitFieldDecl(FieldDecl *D) {
891    // FIXME: add printing of pragma attributes if required.
892    if (!Policy.SuppressSpecifiers && D->isMutable())
893      Out << "mutable ";
894    if (!Policy.SuppressSpecifiers && D->isModulePrivate())
895      Out << "__module_private__ ";
896  
897    Out << D->getASTContext().getUnqualifiedObjCPointerType(D->getType()).
898           stream(Policy, D->getName(), Indentation);
899  
900    if (D->isBitField()) {
901      Out << " : ";
902      D->getBitWidth()->printPretty(Out, nullptr, Policy, Indentation, "\n",
903                                    &Context);
904    }
905  
906    Expr *Init = D->getInClassInitializer();
907    if (!Policy.SuppressInitializers && Init) {
908      if (D->getInClassInitStyle() == ICIS_ListInit)
909        Out << " ";
910      else
911        Out << " = ";
912      Init->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
913    }
914    prettyPrintAttributes(D);
915  }
916  
VisitLabelDecl(LabelDecl * D)917  void DeclPrinter::VisitLabelDecl(LabelDecl *D) {
918    Out << *D << ":";
919  }
920  
VisitVarDecl(VarDecl * D)921  void DeclPrinter::VisitVarDecl(VarDecl *D) {
922    prettyPrintPragmas(D);
923  
924    prettyPrintAttributes(D, AttrPosAsWritten::Left);
925  
926    if (const auto *Param = dyn_cast<ParmVarDecl>(D);
927        Param && Param->isExplicitObjectParameter())
928      Out << "this ";
929  
930    QualType T = D->getTypeSourceInfo()
931      ? D->getTypeSourceInfo()->getType()
932      : D->getASTContext().getUnqualifiedObjCPointerType(D->getType());
933  
934    if (!Policy.SuppressSpecifiers) {
935      StorageClass SC = D->getStorageClass();
936      if (SC != SC_None)
937        Out << VarDecl::getStorageClassSpecifierString(SC) << " ";
938  
939      switch (D->getTSCSpec()) {
940      case TSCS_unspecified:
941        break;
942      case TSCS___thread:
943        Out << "__thread ";
944        break;
945      case TSCS__Thread_local:
946        Out << "_Thread_local ";
947        break;
948      case TSCS_thread_local:
949        Out << "thread_local ";
950        break;
951      }
952  
953      if (D->isModulePrivate())
954        Out << "__module_private__ ";
955  
956      if (D->isConstexpr()) {
957        Out << "constexpr ";
958        T.removeLocalConst();
959      }
960    }
961  
962    if (!Policy.SuppressTagKeyword && Policy.SuppressScope &&
963        !Policy.SuppressUnwrittenScope)
964      MaybePrintTagKeywordIfSupressingScopes(Policy, T, Out);
965  
966    printDeclType(T, (isa<ParmVarDecl>(D) && Policy.CleanUglifiedParameters &&
967                      D->getIdentifier())
968                         ? D->getIdentifier()->deuglifiedName()
969                         : D->getName());
970  
971    prettyPrintAttributes(D, AttrPosAsWritten::Right);
972  
973    Expr *Init = D->getInit();
974    if (!Policy.SuppressInitializers && Init) {
975      bool ImplicitInit = false;
976      if (D->isCXXForRangeDecl()) {
977        // FIXME: We should print the range expression instead.
978        ImplicitInit = true;
979      } else if (CXXConstructExpr *Construct =
980                     dyn_cast<CXXConstructExpr>(Init->IgnoreImplicit())) {
981        if (D->getInitStyle() == VarDecl::CallInit &&
982            !Construct->isListInitialization()) {
983          ImplicitInit = Construct->getNumArgs() == 0 ||
984                         Construct->getArg(0)->isDefaultArgument();
985        }
986      }
987      if (!ImplicitInit) {
988        if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init))
989          Out << "(";
990        else if (D->getInitStyle() == VarDecl::CInit) {
991          Out << " = ";
992        }
993        PrintingPolicy SubPolicy(Policy);
994        SubPolicy.SuppressSpecifiers = false;
995        SubPolicy.IncludeTagDefinition = false;
996        Init->printPretty(Out, nullptr, SubPolicy, Indentation, "\n", &Context);
997        if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init))
998          Out << ")";
999      }
1000    }
1001  }
1002  
VisitParmVarDecl(ParmVarDecl * D)1003  void DeclPrinter::VisitParmVarDecl(ParmVarDecl *D) {
1004    VisitVarDecl(D);
1005  }
1006  
VisitFileScopeAsmDecl(FileScopeAsmDecl * D)1007  void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
1008    Out << "__asm (";
1009    D->getAsmString()->printPretty(Out, nullptr, Policy, Indentation, "\n",
1010                                   &Context);
1011    Out << ")";
1012  }
1013  
VisitTopLevelStmtDecl(TopLevelStmtDecl * D)1014  void DeclPrinter::VisitTopLevelStmtDecl(TopLevelStmtDecl *D) {
1015    assert(D->getStmt());
1016    D->getStmt()->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
1017  }
1018  
VisitImportDecl(ImportDecl * D)1019  void DeclPrinter::VisitImportDecl(ImportDecl *D) {
1020    Out << "@import " << D->getImportedModule()->getFullModuleName()
1021        << ";\n";
1022  }
1023  
VisitStaticAssertDecl(StaticAssertDecl * D)1024  void DeclPrinter::VisitStaticAssertDecl(StaticAssertDecl *D) {
1025    Out << "static_assert(";
1026    D->getAssertExpr()->printPretty(Out, nullptr, Policy, Indentation, "\n",
1027                                    &Context);
1028    if (Expr *E = D->getMessage()) {
1029      Out << ", ";
1030      E->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
1031    }
1032    Out << ")";
1033  }
1034  
1035  //----------------------------------------------------------------------------
1036  // C++ declarations
1037  //----------------------------------------------------------------------------
VisitNamespaceDecl(NamespaceDecl * D)1038  void DeclPrinter::VisitNamespaceDecl(NamespaceDecl *D) {
1039    if (D->isInline())
1040      Out << "inline ";
1041  
1042    Out << "namespace ";
1043    if (D->getDeclName())
1044      Out << D->getDeclName() << ' ';
1045    Out << "{\n";
1046  
1047    VisitDeclContext(D);
1048    Indent() << "}";
1049  }
1050  
VisitUsingDirectiveDecl(UsingDirectiveDecl * D)1051  void DeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1052    Out << "using namespace ";
1053    if (D->getQualifier())
1054      D->getQualifier()->print(Out, Policy);
1055    Out << *D->getNominatedNamespaceAsWritten();
1056  }
1057  
VisitNamespaceAliasDecl(NamespaceAliasDecl * D)1058  void DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1059    Out << "namespace " << *D << " = ";
1060    if (D->getQualifier())
1061      D->getQualifier()->print(Out, Policy);
1062    Out << *D->getAliasedNamespace();
1063  }
1064  
VisitEmptyDecl(EmptyDecl * D)1065  void DeclPrinter::VisitEmptyDecl(EmptyDecl *D) {
1066    prettyPrintAttributes(D);
1067  }
1068  
VisitCXXRecordDecl(CXXRecordDecl * D)1069  void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
1070    // FIXME: add printing of pragma attributes if required.
1071    if (!Policy.SuppressSpecifiers && D->isModulePrivate())
1072      Out << "__module_private__ ";
1073  
1074    Out << D->getKindName() << ' ';
1075  
1076    // FIXME: Move before printing the decl kind to match the behavior of the
1077    // attribute printing for variables and function where they are printed first.
1078    if (prettyPrintAttributes(D, AttrPosAsWritten::Left))
1079      Out << ' ';
1080  
1081    if (D->getIdentifier()) {
1082      if (auto *NNS = D->getQualifier())
1083        NNS->print(Out, Policy);
1084      Out << *D;
1085  
1086      if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1087        const TemplateParameterList *TParams =
1088            S->getSpecializedTemplate()->getTemplateParameters();
1089        const ASTTemplateArgumentListInfo *TArgAsWritten =
1090            S->getTemplateArgsAsWritten();
1091        if (TArgAsWritten && !Policy.PrintCanonicalTypes)
1092          printTemplateArguments(TArgAsWritten->arguments(), TParams);
1093        else
1094          printTemplateArguments(S->getTemplateArgs().asArray(), TParams);
1095      }
1096    }
1097  
1098    prettyPrintAttributes(D, AttrPosAsWritten::Right);
1099  
1100    if (D->isCompleteDefinition()) {
1101      Out << ' ';
1102      // Print the base classes
1103      if (D->getNumBases()) {
1104        Out << ": ";
1105        for (CXXRecordDecl::base_class_iterator Base = D->bases_begin(),
1106               BaseEnd = D->bases_end(); Base != BaseEnd; ++Base) {
1107          if (Base != D->bases_begin())
1108            Out << ", ";
1109  
1110          if (Base->isVirtual())
1111            Out << "virtual ";
1112  
1113          AccessSpecifier AS = Base->getAccessSpecifierAsWritten();
1114          if (AS != AS_none) {
1115            Print(AS);
1116            Out << " ";
1117          }
1118          Out << Base->getType().getAsString(Policy);
1119  
1120          if (Base->isPackExpansion())
1121            Out << "...";
1122        }
1123        Out << ' ';
1124      }
1125  
1126      // Print the class definition
1127      // FIXME: Doesn't print access specifiers, e.g., "public:"
1128      if (Policy.TerseOutput) {
1129        Out << "{}";
1130      } else {
1131        Out << "{\n";
1132        VisitDeclContext(D);
1133        Indent() << "}";
1134      }
1135    }
1136  }
1137  
VisitLinkageSpecDecl(LinkageSpecDecl * D)1138  void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1139    const char *l;
1140    if (D->getLanguage() == LinkageSpecLanguageIDs::C)
1141      l = "C";
1142    else {
1143      assert(D->getLanguage() == LinkageSpecLanguageIDs::CXX &&
1144             "unknown language in linkage specification");
1145      l = "C++";
1146    }
1147  
1148    Out << "extern \"" << l << "\" ";
1149    if (D->hasBraces()) {
1150      Out << "{\n";
1151      VisitDeclContext(D);
1152      Indent() << "}";
1153    } else
1154      Visit(*D->decls_begin());
1155  }
1156  
printTemplateParameters(const TemplateParameterList * Params,bool OmitTemplateKW)1157  void DeclPrinter::printTemplateParameters(const TemplateParameterList *Params,
1158                                            bool OmitTemplateKW) {
1159    assert(Params);
1160  
1161    // Don't print invented template parameter lists.
1162    if (!Params->empty() && Params->getParam(0)->isImplicit())
1163      return;
1164  
1165    if (!OmitTemplateKW)
1166      Out << "template ";
1167    Out << '<';
1168  
1169    bool NeedComma = false;
1170    for (const Decl *Param : *Params) {
1171      if (Param->isImplicit())
1172        continue;
1173  
1174      if (NeedComma)
1175        Out << ", ";
1176      else
1177        NeedComma = true;
1178  
1179      if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
1180        VisitTemplateTypeParmDecl(TTP);
1181      } else if (auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
1182        VisitNonTypeTemplateParmDecl(NTTP);
1183      } else if (auto TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
1184        VisitTemplateDecl(TTPD);
1185        // FIXME: print the default argument, if present.
1186      }
1187    }
1188  
1189    Out << '>';
1190  
1191    if (const Expr *RequiresClause = Params->getRequiresClause()) {
1192      Out << " requires ";
1193      RequiresClause->printPretty(Out, nullptr, Policy, Indentation, "\n",
1194                                  &Context);
1195    }
1196  
1197    if (!OmitTemplateKW)
1198      Out << ' ';
1199  }
1200  
printTemplateArguments(ArrayRef<TemplateArgument> Args,const TemplateParameterList * Params)1201  void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgument> Args,
1202                                           const TemplateParameterList *Params) {
1203    Out << "<";
1204    for (size_t I = 0, E = Args.size(); I < E; ++I) {
1205      if (I)
1206        Out << ", ";
1207      if (!Params)
1208        Args[I].print(Policy, Out, /*IncludeType*/ true);
1209      else
1210        Args[I].print(Policy, Out,
1211                      TemplateParameterList::shouldIncludeTypeForArgument(
1212                          Policy, Params, I));
1213    }
1214    Out << ">";
1215  }
1216  
printTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,const TemplateParameterList * Params)1217  void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
1218                                           const TemplateParameterList *Params) {
1219    Out << "<";
1220    for (size_t I = 0, E = Args.size(); I < E; ++I) {
1221      if (I)
1222        Out << ", ";
1223      if (!Params)
1224        Args[I].getArgument().print(Policy, Out, /*IncludeType*/ true);
1225      else
1226        Args[I].getArgument().print(
1227            Policy, Out,
1228            TemplateParameterList::shouldIncludeTypeForArgument(Policy, Params,
1229                                                                I));
1230    }
1231    Out << ">";
1232  }
1233  
VisitTemplateDecl(const TemplateDecl * D)1234  void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
1235    printTemplateParameters(D->getTemplateParameters());
1236  
1237    if (const TemplateTemplateParmDecl *TTP =
1238          dyn_cast<TemplateTemplateParmDecl>(D)) {
1239      if (TTP->wasDeclaredWithTypename())
1240        Out << "typename";
1241      else
1242        Out << "class";
1243  
1244      if (TTP->isParameterPack())
1245        Out << " ...";
1246      else if (TTP->getDeclName())
1247        Out << ' ';
1248  
1249      if (TTP->getDeclName()) {
1250        if (Policy.CleanUglifiedParameters && TTP->getIdentifier())
1251          Out << TTP->getIdentifier()->deuglifiedName();
1252        else
1253          Out << TTP->getDeclName();
1254      }
1255    } else if (auto *TD = D->getTemplatedDecl())
1256      Visit(TD);
1257    else if (const auto *Concept = dyn_cast<ConceptDecl>(D)) {
1258      Out << "concept " << Concept->getName() << " = " ;
1259      Concept->getConstraintExpr()->printPretty(Out, nullptr, Policy, Indentation,
1260                                                "\n", &Context);
1261    }
1262  }
1263  
VisitFunctionTemplateDecl(FunctionTemplateDecl * D)1264  void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
1265    prettyPrintPragmas(D->getTemplatedDecl());
1266    // Print any leading template parameter lists.
1267    if (const FunctionDecl *FD = D->getTemplatedDecl()) {
1268      for (unsigned I = 0, NumTemplateParams = FD->getNumTemplateParameterLists();
1269           I < NumTemplateParams; ++I)
1270        printTemplateParameters(FD->getTemplateParameterList(I));
1271    }
1272    VisitRedeclarableTemplateDecl(D);
1273    // Declare target attribute is special one, natural spelling for the pragma
1274    // assumes "ending" construct so print it here.
1275    if (D->getTemplatedDecl()->hasAttr<OMPDeclareTargetDeclAttr>())
1276      Out << "#pragma omp end declare target\n";
1277  
1278    // Never print "instantiations" for deduction guides (they don't really
1279    // have them).
1280    if (PrintInstantiation &&
1281        !isa<CXXDeductionGuideDecl>(D->getTemplatedDecl())) {
1282      FunctionDecl *PrevDecl = D->getTemplatedDecl();
1283      const FunctionDecl *Def;
1284      if (PrevDecl->isDefined(Def) && Def != PrevDecl)
1285        return;
1286      for (auto *I : D->specializations())
1287        if (I->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) {
1288          if (!PrevDecl->isThisDeclarationADefinition())
1289            Out << ";\n";
1290          Indent();
1291          prettyPrintPragmas(I);
1292          Visit(I);
1293        }
1294    }
1295  }
1296  
VisitClassTemplateDecl(ClassTemplateDecl * D)1297  void DeclPrinter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
1298    VisitRedeclarableTemplateDecl(D);
1299  
1300    if (PrintInstantiation) {
1301      for (auto *I : D->specializations())
1302        if (I->getSpecializationKind() == TSK_ImplicitInstantiation) {
1303          if (D->isThisDeclarationADefinition())
1304            Out << ";";
1305          Out << "\n";
1306          Indent();
1307          Visit(I);
1308        }
1309    }
1310  }
1311  
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl * D)1312  void DeclPrinter::VisitClassTemplateSpecializationDecl(
1313                                             ClassTemplateSpecializationDecl *D) {
1314    Out << "template<> ";
1315    VisitCXXRecordDecl(D);
1316  }
1317  
VisitClassTemplatePartialSpecializationDecl(ClassTemplatePartialSpecializationDecl * D)1318  void DeclPrinter::VisitClassTemplatePartialSpecializationDecl(
1319                                      ClassTemplatePartialSpecializationDecl *D) {
1320    printTemplateParameters(D->getTemplateParameters());
1321    VisitCXXRecordDecl(D);
1322  }
1323  
1324  //----------------------------------------------------------------------------
1325  // Objective-C declarations
1326  //----------------------------------------------------------------------------
1327  
PrintObjCMethodType(ASTContext & Ctx,Decl::ObjCDeclQualifier Quals,QualType T)1328  void DeclPrinter::PrintObjCMethodType(ASTContext &Ctx,
1329                                        Decl::ObjCDeclQualifier Quals,
1330                                        QualType T) {
1331    Out << '(';
1332    if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_In)
1333      Out << "in ";
1334    if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_Inout)
1335      Out << "inout ";
1336    if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_Out)
1337      Out << "out ";
1338    if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_Bycopy)
1339      Out << "bycopy ";
1340    if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_Byref)
1341      Out << "byref ";
1342    if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_Oneway)
1343      Out << "oneway ";
1344    if (Quals & Decl::ObjCDeclQualifier::OBJC_TQ_CSNullability) {
1345      if (auto nullability = AttributedType::stripOuterNullability(T))
1346        Out << getNullabilitySpelling(*nullability, true) << ' ';
1347    }
1348  
1349    Out << Ctx.getUnqualifiedObjCPointerType(T).getAsString(Policy);
1350    Out << ')';
1351  }
1352  
PrintObjCTypeParams(ObjCTypeParamList * Params)1353  void DeclPrinter::PrintObjCTypeParams(ObjCTypeParamList *Params) {
1354    Out << "<";
1355    unsigned First = true;
1356    for (auto *Param : *Params) {
1357      if (First) {
1358        First = false;
1359      } else {
1360        Out << ", ";
1361      }
1362  
1363      switch (Param->getVariance()) {
1364      case ObjCTypeParamVariance::Invariant:
1365        break;
1366  
1367      case ObjCTypeParamVariance::Covariant:
1368        Out << "__covariant ";
1369        break;
1370  
1371      case ObjCTypeParamVariance::Contravariant:
1372        Out << "__contravariant ";
1373        break;
1374      }
1375  
1376      Out << Param->getDeclName();
1377  
1378      if (Param->hasExplicitBound()) {
1379        Out << " : " << Param->getUnderlyingType().getAsString(Policy);
1380      }
1381    }
1382    Out << ">";
1383  }
1384  
VisitObjCMethodDecl(ObjCMethodDecl * OMD)1385  void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) {
1386    if (OMD->isInstanceMethod())
1387      Out << "- ";
1388    else
1389      Out << "+ ";
1390    if (!OMD->getReturnType().isNull()) {
1391      PrintObjCMethodType(OMD->getASTContext(), OMD->getObjCDeclQualifier(),
1392                          OMD->getReturnType());
1393    }
1394  
1395    std::string name = OMD->getSelector().getAsString();
1396    std::string::size_type pos, lastPos = 0;
1397    for (const auto *PI : OMD->parameters()) {
1398      // FIXME: selector is missing here!
1399      pos = name.find_first_of(':', lastPos);
1400      if (lastPos != 0)
1401        Out << " ";
1402      Out << name.substr(lastPos, pos - lastPos) << ':';
1403      PrintObjCMethodType(OMD->getASTContext(),
1404                          PI->getObjCDeclQualifier(),
1405                          PI->getType());
1406      Out << *PI;
1407      lastPos = pos + 1;
1408    }
1409  
1410    if (OMD->param_begin() == OMD->param_end())
1411      Out << name;
1412  
1413    if (OMD->isVariadic())
1414        Out << ", ...";
1415  
1416    prettyPrintAttributes(OMD);
1417  
1418    if (OMD->getBody() && !Policy.TerseOutput) {
1419      Out << ' ';
1420      OMD->getBody()->printPretty(Out, nullptr, Policy, Indentation, "\n",
1421                                  &Context);
1422    }
1423    else if (Policy.PolishForDeclaration)
1424      Out << ';';
1425  }
1426  
VisitObjCImplementationDecl(ObjCImplementationDecl * OID)1427  void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) {
1428    std::string I = OID->getNameAsString();
1429    ObjCInterfaceDecl *SID = OID->getSuperClass();
1430  
1431    bool eolnOut = false;
1432    if (SID)
1433      Out << "@implementation " << I << " : " << *SID;
1434    else
1435      Out << "@implementation " << I;
1436  
1437    if (OID->ivar_size() > 0) {
1438      Out << "{\n";
1439      eolnOut = true;
1440      Indentation += Policy.Indentation;
1441      for (const auto *I : OID->ivars()) {
1442        Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
1443                      getAsString(Policy) << ' ' << *I << ";\n";
1444      }
1445      Indentation -= Policy.Indentation;
1446      Out << "}\n";
1447    }
1448    else if (SID || (OID->decls_begin() != OID->decls_end())) {
1449      Out << "\n";
1450      eolnOut = true;
1451    }
1452    VisitDeclContext(OID, false);
1453    if (!eolnOut)
1454      Out << "\n";
1455    Out << "@end";
1456  }
1457  
VisitObjCInterfaceDecl(ObjCInterfaceDecl * OID)1458  void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
1459    std::string I = OID->getNameAsString();
1460    ObjCInterfaceDecl *SID = OID->getSuperClass();
1461  
1462    if (!OID->isThisDeclarationADefinition()) {
1463      Out << "@class " << I;
1464  
1465      if (auto TypeParams = OID->getTypeParamListAsWritten()) {
1466        PrintObjCTypeParams(TypeParams);
1467      }
1468  
1469      Out << ";";
1470      return;
1471    }
1472    bool eolnOut = false;
1473    if (OID->hasAttrs()) {
1474      prettyPrintAttributes(OID);
1475      Out << "\n";
1476    }
1477  
1478    Out << "@interface " << I;
1479  
1480    if (auto TypeParams = OID->getTypeParamListAsWritten()) {
1481      PrintObjCTypeParams(TypeParams);
1482    }
1483  
1484    if (SID)
1485      Out << " : " << QualType(OID->getSuperClassType(), 0).getAsString(Policy);
1486  
1487    // Protocols?
1488    const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();
1489    if (!Protocols.empty()) {
1490      for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
1491           E = Protocols.end(); I != E; ++I)
1492        Out << (I == Protocols.begin() ? '<' : ',') << **I;
1493      Out << "> ";
1494    }
1495  
1496    if (OID->ivar_size() > 0) {
1497      Out << "{\n";
1498      eolnOut = true;
1499      Indentation += Policy.Indentation;
1500      for (const auto *I : OID->ivars()) {
1501        Indent() << I->getASTContext()
1502                        .getUnqualifiedObjCPointerType(I->getType())
1503                        .getAsString(Policy) << ' ' << *I << ";\n";
1504      }
1505      Indentation -= Policy.Indentation;
1506      Out << "}\n";
1507    }
1508    else if (SID || (OID->decls_begin() != OID->decls_end())) {
1509      Out << "\n";
1510      eolnOut = true;
1511    }
1512  
1513    VisitDeclContext(OID, false);
1514    if (!eolnOut)
1515      Out << "\n";
1516    Out << "@end";
1517    // FIXME: implement the rest...
1518  }
1519  
VisitObjCProtocolDecl(ObjCProtocolDecl * PID)1520  void DeclPrinter::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1521    if (!PID->isThisDeclarationADefinition()) {
1522      Out << "@protocol " << *PID << ";\n";
1523      return;
1524    }
1525    // Protocols?
1526    const ObjCList<ObjCProtocolDecl> &Protocols = PID->getReferencedProtocols();
1527    if (!Protocols.empty()) {
1528      Out << "@protocol " << *PID;
1529      for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
1530           E = Protocols.end(); I != E; ++I)
1531        Out << (I == Protocols.begin() ? '<' : ',') << **I;
1532      Out << ">\n";
1533    } else
1534      Out << "@protocol " << *PID << '\n';
1535    VisitDeclContext(PID, false);
1536    Out << "@end";
1537  }
1538  
VisitObjCCategoryImplDecl(ObjCCategoryImplDecl * PID)1539  void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) {
1540    Out << "@implementation ";
1541    if (const auto *CID = PID->getClassInterface())
1542      Out << *CID;
1543    else
1544      Out << "<<error-type>>";
1545    Out << '(' << *PID << ")\n";
1546  
1547    VisitDeclContext(PID, false);
1548    Out << "@end";
1549    // FIXME: implement the rest...
1550  }
1551  
VisitObjCCategoryDecl(ObjCCategoryDecl * PID)1552  void DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) {
1553    Out << "@interface ";
1554    if (const auto *CID = PID->getClassInterface())
1555      Out << *CID;
1556    else
1557      Out << "<<error-type>>";
1558    if (auto TypeParams = PID->getTypeParamList()) {
1559      PrintObjCTypeParams(TypeParams);
1560    }
1561    Out << "(" << *PID << ")\n";
1562    if (PID->ivar_size() > 0) {
1563      Out << "{\n";
1564      Indentation += Policy.Indentation;
1565      for (const auto *I : PID->ivars())
1566        Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
1567                      getAsString(Policy) << ' ' << *I << ";\n";
1568      Indentation -= Policy.Indentation;
1569      Out << "}\n";
1570    }
1571  
1572    VisitDeclContext(PID, false);
1573    Out << "@end";
1574  
1575    // FIXME: implement the rest...
1576  }
1577  
VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl * AID)1578  void DeclPrinter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID) {
1579    Out << "@compatibility_alias " << *AID
1580        << ' ' << *AID->getClassInterface() << ";\n";
1581  }
1582  
1583  /// PrintObjCPropertyDecl - print a property declaration.
1584  ///
1585  /// Print attributes in the following order:
1586  /// - class
1587  /// - nonatomic | atomic
1588  /// - assign | retain | strong | copy | weak | unsafe_unretained
1589  /// - readwrite | readonly
1590  /// - getter & setter
1591  /// - nullability
VisitObjCPropertyDecl(ObjCPropertyDecl * PDecl)1592  void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
1593    if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Required)
1594      Out << "@required\n";
1595    else if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Optional)
1596      Out << "@optional\n";
1597  
1598    QualType T = PDecl->getType();
1599  
1600    Out << "@property";
1601    if (PDecl->getPropertyAttributes() != ObjCPropertyAttribute::kind_noattr) {
1602      bool first = true;
1603      Out << "(";
1604      if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_class) {
1605        Out << (first ? "" : ", ") << "class";
1606        first = false;
1607      }
1608  
1609      if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_direct) {
1610        Out << (first ? "" : ", ") << "direct";
1611        first = false;
1612      }
1613  
1614      if (PDecl->getPropertyAttributes() &
1615          ObjCPropertyAttribute::kind_nonatomic) {
1616        Out << (first ? "" : ", ") << "nonatomic";
1617        first = false;
1618      }
1619      if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_atomic) {
1620        Out << (first ? "" : ", ") << "atomic";
1621        first = false;
1622      }
1623  
1624      if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_assign) {
1625        Out << (first ? "" : ", ") << "assign";
1626        first = false;
1627      }
1628      if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_retain) {
1629        Out << (first ? "" : ", ") << "retain";
1630        first = false;
1631      }
1632  
1633      if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_strong) {
1634        Out << (first ? "" : ", ") << "strong";
1635        first = false;
1636      }
1637      if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_copy) {
1638        Out << (first ? "" : ", ") << "copy";
1639        first = false;
1640      }
1641      if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak) {
1642        Out << (first ? "" : ", ") << "weak";
1643        first = false;
1644      }
1645      if (PDecl->getPropertyAttributes() &
1646          ObjCPropertyAttribute::kind_unsafe_unretained) {
1647        Out << (first ? "" : ", ") << "unsafe_unretained";
1648        first = false;
1649      }
1650  
1651      if (PDecl->getPropertyAttributes() &
1652          ObjCPropertyAttribute::kind_readwrite) {
1653        Out << (first ? "" : ", ") << "readwrite";
1654        first = false;
1655      }
1656      if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_readonly) {
1657        Out << (first ? "" : ", ") << "readonly";
1658        first = false;
1659      }
1660  
1661      if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_getter) {
1662        Out << (first ? "" : ", ") << "getter = ";
1663        PDecl->getGetterName().print(Out);
1664        first = false;
1665      }
1666      if (PDecl->getPropertyAttributes() & ObjCPropertyAttribute::kind_setter) {
1667        Out << (first ? "" : ", ") << "setter = ";
1668        PDecl->getSetterName().print(Out);
1669        first = false;
1670      }
1671  
1672      if (PDecl->getPropertyAttributes() &
1673          ObjCPropertyAttribute::kind_nullability) {
1674        if (auto nullability = AttributedType::stripOuterNullability(T)) {
1675          if (*nullability == NullabilityKind::Unspecified &&
1676              (PDecl->getPropertyAttributes() &
1677               ObjCPropertyAttribute::kind_null_resettable)) {
1678            Out << (first ? "" : ", ") << "null_resettable";
1679          } else {
1680            Out << (first ? "" : ", ")
1681                << getNullabilitySpelling(*nullability, true);
1682          }
1683          first = false;
1684        }
1685      }
1686  
1687      (void) first; // Silence dead store warning due to idiomatic code.
1688      Out << ")";
1689    }
1690    std::string TypeStr = PDecl->getASTContext().getUnqualifiedObjCPointerType(T).
1691        getAsString(Policy);
1692    Out << ' ' << TypeStr;
1693    if (!StringRef(TypeStr).ends_with("*"))
1694      Out << ' ';
1695    Out << *PDecl;
1696    if (Policy.PolishForDeclaration)
1697      Out << ';';
1698  }
1699  
VisitObjCPropertyImplDecl(ObjCPropertyImplDecl * PID)1700  void DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) {
1701    if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize)
1702      Out << "@synthesize ";
1703    else
1704      Out << "@dynamic ";
1705    Out << *PID->getPropertyDecl();
1706    if (PID->getPropertyIvarDecl())
1707      Out << '=' << *PID->getPropertyIvarDecl();
1708  }
1709  
VisitUsingDecl(UsingDecl * D)1710  void DeclPrinter::VisitUsingDecl(UsingDecl *D) {
1711    if (!D->isAccessDeclaration())
1712      Out << "using ";
1713    if (D->hasTypename())
1714      Out << "typename ";
1715    D->getQualifier()->print(Out, Policy);
1716  
1717    // Use the correct record name when the using declaration is used for
1718    // inheriting constructors.
1719    for (const auto *Shadow : D->shadows()) {
1720      if (const auto *ConstructorShadow =
1721              dyn_cast<ConstructorUsingShadowDecl>(Shadow)) {
1722        assert(Shadow->getDeclContext() == ConstructorShadow->getDeclContext());
1723        Out << *ConstructorShadow->getNominatedBaseClass();
1724        return;
1725      }
1726    }
1727    Out << *D;
1728  }
1729  
VisitUsingEnumDecl(UsingEnumDecl * D)1730  void DeclPrinter::VisitUsingEnumDecl(UsingEnumDecl *D) {
1731    Out << "using enum " << D->getEnumDecl();
1732  }
1733  
1734  void
VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl * D)1735  DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
1736    Out << "using typename ";
1737    D->getQualifier()->print(Out, Policy);
1738    Out << D->getDeclName();
1739  }
1740  
VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl * D)1741  void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1742    if (!D->isAccessDeclaration())
1743      Out << "using ";
1744    D->getQualifier()->print(Out, Policy);
1745    Out << D->getDeclName();
1746  }
1747  
VisitUsingShadowDecl(UsingShadowDecl * D)1748  void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) {
1749    // ignore
1750  }
1751  
VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl * D)1752  void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
1753    Out << "#pragma omp threadprivate";
1754    if (!D->varlist_empty()) {
1755      for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(),
1756                                                  E = D->varlist_end();
1757                                                  I != E; ++I) {
1758        Out << (I == D->varlist_begin() ? '(' : ',');
1759        NamedDecl *ND = cast<DeclRefExpr>(*I)->getDecl();
1760        ND->printQualifiedName(Out);
1761      }
1762      Out << ")";
1763    }
1764  }
1765  
VisitHLSLBufferDecl(HLSLBufferDecl * D)1766  void DeclPrinter::VisitHLSLBufferDecl(HLSLBufferDecl *D) {
1767    if (D->isCBuffer())
1768      Out << "cbuffer ";
1769    else
1770      Out << "tbuffer ";
1771  
1772    Out << *D;
1773  
1774    prettyPrintAttributes(D);
1775  
1776    Out << " {\n";
1777    VisitDeclContext(D);
1778    Indent() << "}";
1779  }
1780  
VisitOMPAllocateDecl(OMPAllocateDecl * D)1781  void DeclPrinter::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
1782    Out << "#pragma omp allocate";
1783    if (!D->varlist_empty()) {
1784      for (OMPAllocateDecl::varlist_iterator I = D->varlist_begin(),
1785                                             E = D->varlist_end();
1786           I != E; ++I) {
1787        Out << (I == D->varlist_begin() ? '(' : ',');
1788        NamedDecl *ND = cast<DeclRefExpr>(*I)->getDecl();
1789        ND->printQualifiedName(Out);
1790      }
1791      Out << ")";
1792    }
1793    if (!D->clauselist_empty()) {
1794      OMPClausePrinter Printer(Out, Policy);
1795      for (OMPClause *C : D->clauselists()) {
1796        Out << " ";
1797        Printer.Visit(C);
1798      }
1799    }
1800  }
1801  
VisitOMPRequiresDecl(OMPRequiresDecl * D)1802  void DeclPrinter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
1803    Out << "#pragma omp requires ";
1804    if (!D->clauselist_empty()) {
1805      OMPClausePrinter Printer(Out, Policy);
1806      for (auto I = D->clauselist_begin(), E = D->clauselist_end(); I != E; ++I)
1807        Printer.Visit(*I);
1808    }
1809  }
1810  
VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl * D)1811  void DeclPrinter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
1812    if (!D->isInvalidDecl()) {
1813      Out << "#pragma omp declare reduction (";
1814      if (D->getDeclName().getNameKind() == DeclarationName::CXXOperatorName) {
1815        const char *OpName =
1816            getOperatorSpelling(D->getDeclName().getCXXOverloadedOperator());
1817        assert(OpName && "not an overloaded operator");
1818        Out << OpName;
1819      } else {
1820        assert(D->getDeclName().isIdentifier());
1821        D->printName(Out, Policy);
1822      }
1823      Out << " : ";
1824      D->getType().print(Out, Policy);
1825      Out << " : ";
1826      D->getCombiner()->printPretty(Out, nullptr, Policy, 0, "\n", &Context);
1827      Out << ")";
1828      if (auto *Init = D->getInitializer()) {
1829        Out << " initializer(";
1830        switch (D->getInitializerKind()) {
1831        case OMPDeclareReductionInitKind::Direct:
1832          Out << "omp_priv(";
1833          break;
1834        case OMPDeclareReductionInitKind::Copy:
1835          Out << "omp_priv = ";
1836          break;
1837        case OMPDeclareReductionInitKind::Call:
1838          break;
1839        }
1840        Init->printPretty(Out, nullptr, Policy, 0, "\n", &Context);
1841        if (D->getInitializerKind() == OMPDeclareReductionInitKind::Direct)
1842          Out << ")";
1843        Out << ")";
1844      }
1845    }
1846  }
1847  
VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl * D)1848  void DeclPrinter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
1849    if (!D->isInvalidDecl()) {
1850      Out << "#pragma omp declare mapper (";
1851      D->printName(Out, Policy);
1852      Out << " : ";
1853      D->getType().print(Out, Policy);
1854      Out << " ";
1855      Out << D->getVarName();
1856      Out << ")";
1857      if (!D->clauselist_empty()) {
1858        OMPClausePrinter Printer(Out, Policy);
1859        for (auto *C : D->clauselists()) {
1860          Out << " ";
1861          Printer.Visit(C);
1862        }
1863      }
1864    }
1865  }
1866  
VisitOMPCapturedExprDecl(OMPCapturedExprDecl * D)1867  void DeclPrinter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
1868    D->getInit()->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
1869  }
1870  
VisitTemplateTypeParmDecl(const TemplateTypeParmDecl * TTP)1871  void DeclPrinter::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *TTP) {
1872    if (const TypeConstraint *TC = TTP->getTypeConstraint())
1873      TC->print(Out, Policy);
1874    else if (TTP->wasDeclaredWithTypename())
1875      Out << "typename";
1876    else
1877      Out << "class";
1878  
1879    if (TTP->isParameterPack())
1880      Out << " ...";
1881    else if (TTP->getDeclName())
1882      Out << ' ';
1883  
1884    if (TTP->getDeclName()) {
1885      if (Policy.CleanUglifiedParameters && TTP->getIdentifier())
1886        Out << TTP->getIdentifier()->deuglifiedName();
1887      else
1888        Out << TTP->getDeclName();
1889    }
1890  
1891    if (TTP->hasDefaultArgument()) {
1892      Out << " = ";
1893      TTP->getDefaultArgument().getArgument().print(Policy, Out,
1894                                                    /*IncludeType=*/false);
1895    }
1896  }
1897  
VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl * NTTP)1898  void DeclPrinter::VisitNonTypeTemplateParmDecl(
1899      const NonTypeTemplateParmDecl *NTTP) {
1900    StringRef Name;
1901    if (IdentifierInfo *II = NTTP->getIdentifier())
1902      Name =
1903          Policy.CleanUglifiedParameters ? II->deuglifiedName() : II->getName();
1904    printDeclType(NTTP->getType(), Name, NTTP->isParameterPack());
1905  
1906    if (NTTP->hasDefaultArgument()) {
1907      Out << " = ";
1908      NTTP->getDefaultArgument().getArgument().print(Policy, Out,
1909                                                     /*IncludeType=*/false);
1910    }
1911  }
1912