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