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