DeclPrinter.cpp revision 234353
1193326Sed//===--- DeclPrinter.cpp - Printing implementation for Decl ASTs ----------===// 2193326Sed// 3193326Sed// The LLVM Compiler Infrastructure 4193326Sed// 5193326Sed// This file is distributed under the University of Illinois Open Source 6193326Sed// License. See LICENSE.TXT for details. 7193326Sed// 8193326Sed//===----------------------------------------------------------------------===// 9193326Sed// 10193326Sed// This file implements the Decl::dump method, which pretty print the 11193326Sed// AST back out to C/Objective-C/C++/Objective-C++ code. 12193326Sed// 13193326Sed//===----------------------------------------------------------------------===// 14193326Sed#include "clang/AST/ASTContext.h" 15193326Sed#include "clang/AST/DeclVisitor.h" 16193326Sed#include "clang/AST/Decl.h" 17193326Sed#include "clang/AST/DeclCXX.h" 18193326Sed#include "clang/AST/DeclObjC.h" 19193326Sed#include "clang/AST/Expr.h" 20203955Srdivacky#include "clang/AST/ExprCXX.h" 21193326Sed#include "clang/AST/PrettyPrinter.h" 22234353Sdim#include "clang/Basic/Module.h" 23193326Sed#include "llvm/Support/raw_ostream.h" 24193326Sedusing namespace clang; 25193326Sed 26193326Sednamespace { 27199990Srdivacky class DeclPrinter : public DeclVisitor<DeclPrinter> { 28226633Sdim raw_ostream &Out; 29193326Sed ASTContext &Context; 30193326Sed PrintingPolicy Policy; 31193326Sed unsigned Indentation; 32226633Sdim bool PrintInstantiation; 33193326Sed 34226633Sdim raw_ostream& Indent() { return Indent(Indentation); } 35226633Sdim raw_ostream& Indent(unsigned Indentation); 36226633Sdim void ProcessDeclGroup(SmallVectorImpl<Decl*>& Decls); 37193326Sed 38198092Srdivacky void Print(AccessSpecifier AS); 39198092Srdivacky 40193326Sed public: 41226633Sdim DeclPrinter(raw_ostream &Out, ASTContext &Context, 42193326Sed const PrintingPolicy &Policy, 43226633Sdim unsigned Indentation = 0, 44226633Sdim bool PrintInstantiation = false) 45226633Sdim : Out(Out), Context(Context), Policy(Policy), Indentation(Indentation), 46226633Sdim PrintInstantiation(PrintInstantiation) { } 47193326Sed 48193326Sed void VisitDeclContext(DeclContext *DC, bool Indent = true); 49193326Sed 50193326Sed void VisitTranslationUnitDecl(TranslationUnitDecl *D); 51193326Sed void VisitTypedefDecl(TypedefDecl *D); 52221345Sdim void VisitTypeAliasDecl(TypeAliasDecl *D); 53193326Sed void VisitEnumDecl(EnumDecl *D); 54193326Sed void VisitRecordDecl(RecordDecl *D); 55193326Sed void VisitEnumConstantDecl(EnumConstantDecl *D); 56193326Sed void VisitFunctionDecl(FunctionDecl *D); 57193326Sed void VisitFieldDecl(FieldDecl *D); 58193326Sed void VisitVarDecl(VarDecl *D); 59218893Sdim void VisitLabelDecl(LabelDecl *D); 60193326Sed void VisitParmVarDecl(ParmVarDecl *D); 61193326Sed void VisitFileScopeAsmDecl(FileScopeAsmDecl *D); 62234353Sdim void VisitImportDecl(ImportDecl *D); 63221345Sdim void VisitStaticAssertDecl(StaticAssertDecl *D); 64193326Sed void VisitNamespaceDecl(NamespaceDecl *D); 65193326Sed void VisitUsingDirectiveDecl(UsingDirectiveDecl *D); 66193326Sed void VisitNamespaceAliasDecl(NamespaceAliasDecl *D); 67193326Sed void VisitCXXRecordDecl(CXXRecordDecl *D); 68193326Sed void VisitLinkageSpecDecl(LinkageSpecDecl *D); 69221345Sdim void VisitTemplateDecl(const TemplateDecl *D); 70226633Sdim void VisitFunctionTemplateDecl(FunctionTemplateDecl *D); 71226633Sdim void VisitClassTemplateDecl(ClassTemplateDecl *D); 72193326Sed void VisitObjCMethodDecl(ObjCMethodDecl *D); 73193326Sed void VisitObjCImplementationDecl(ObjCImplementationDecl *D); 74193326Sed void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D); 75193326Sed void VisitObjCProtocolDecl(ObjCProtocolDecl *D); 76193326Sed void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D); 77193326Sed void VisitObjCCategoryDecl(ObjCCategoryDecl *D); 78193326Sed void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D); 79193326Sed void VisitObjCPropertyDecl(ObjCPropertyDecl *D); 80193326Sed void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D); 81199482Srdivacky void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D); 82199482Srdivacky void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D); 83198092Srdivacky void VisitUsingDecl(UsingDecl *D); 84199482Srdivacky void VisitUsingShadowDecl(UsingShadowDecl *D); 85226633Sdim 86226633Sdim void PrintTemplateParameters(const TemplateParameterList *Params, 87226633Sdim const TemplateArgumentList *Args); 88234353Sdim void prettyPrintAttributes(Decl *D); 89193326Sed }; 90193326Sed} 91193326Sed 92226633Sdimvoid Decl::print(raw_ostream &Out, unsigned Indentation, 93226633Sdim bool PrintInstantiation) const { 94226633Sdim print(Out, getASTContext().getPrintingPolicy(), Indentation, PrintInstantiation); 95193326Sed} 96193326Sed 97226633Sdimvoid Decl::print(raw_ostream &Out, const PrintingPolicy &Policy, 98226633Sdim unsigned Indentation, bool PrintInstantiation) const { 99226633Sdim DeclPrinter Printer(Out, getASTContext(), Policy, Indentation, PrintInstantiation); 100198092Srdivacky Printer.Visit(const_cast<Decl*>(this)); 101193326Sed} 102193326Sed 103193326Sedstatic QualType GetBaseType(QualType T) { 104193326Sed // FIXME: This should be on the Type class! 105193326Sed QualType BaseType = T; 106193326Sed while (!BaseType->isSpecifierType()) { 107193326Sed if (isa<TypedefType>(BaseType)) 108193326Sed break; 109198092Srdivacky else if (const PointerType* PTy = BaseType->getAs<PointerType>()) 110193326Sed BaseType = PTy->getPointeeType(); 111193326Sed else if (const ArrayType* ATy = dyn_cast<ArrayType>(BaseType)) 112193326Sed BaseType = ATy->getElementType(); 113198092Srdivacky else if (const FunctionType* FTy = BaseType->getAs<FunctionType>()) 114193326Sed BaseType = FTy->getResultType(); 115198092Srdivacky else if (const VectorType *VTy = BaseType->getAs<VectorType>()) 116195341Sed BaseType = VTy->getElementType(); 117193326Sed else 118226633Sdim llvm_unreachable("Unknown declarator!"); 119193326Sed } 120193326Sed return BaseType; 121193326Sed} 122193326Sed 123193326Sedstatic QualType getDeclType(Decl* D) { 124221345Sdim if (TypedefNameDecl* TDD = dyn_cast<TypedefNameDecl>(D)) 125193326Sed return TDD->getUnderlyingType(); 126193326Sed if (ValueDecl* VD = dyn_cast<ValueDecl>(D)) 127193326Sed return VD->getType(); 128193326Sed return QualType(); 129193326Sed} 130193326Sed 131193326Sedvoid Decl::printGroup(Decl** Begin, unsigned NumDecls, 132226633Sdim raw_ostream &Out, const PrintingPolicy &Policy, 133193326Sed unsigned Indentation) { 134193326Sed if (NumDecls == 1) { 135195341Sed (*Begin)->print(Out, Policy, Indentation); 136193326Sed return; 137193326Sed } 138193326Sed 139193326Sed Decl** End = Begin + NumDecls; 140193326Sed TagDecl* TD = dyn_cast<TagDecl>(*Begin); 141193326Sed if (TD) 142193326Sed ++Begin; 143193326Sed 144193326Sed PrintingPolicy SubPolicy(Policy); 145226633Sdim if (TD && TD->isCompleteDefinition()) { 146195341Sed TD->print(Out, Policy, Indentation); 147193326Sed Out << " "; 148193326Sed SubPolicy.SuppressTag = true; 149193326Sed } 150193326Sed 151193326Sed bool isFirst = true; 152193326Sed for ( ; Begin != End; ++Begin) { 153193326Sed if (isFirst) { 154193326Sed SubPolicy.SuppressSpecifiers = false; 155193326Sed isFirst = false; 156193326Sed } else { 157193326Sed if (!isFirst) Out << ", "; 158193326Sed SubPolicy.SuppressSpecifiers = true; 159193326Sed } 160193326Sed 161195341Sed (*Begin)->print(Out, SubPolicy, Indentation); 162193326Sed } 163193326Sed} 164193326Sed 165200583Srdivackyvoid DeclContext::dumpDeclContext() const { 166200583Srdivacky // Get the translation unit 167200583Srdivacky const DeclContext *DC = this; 168200583Srdivacky while (!DC->isTranslationUnit()) 169200583Srdivacky DC = DC->getParent(); 170200583Srdivacky 171200583Srdivacky ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext(); 172226633Sdim DeclPrinter Printer(llvm::errs(), Ctx, Ctx.getPrintingPolicy(), 0); 173200583Srdivacky Printer.VisitDeclContext(const_cast<DeclContext *>(this), /*Indent=*/false); 174200583Srdivacky} 175200583Srdivacky 176198092Srdivackyvoid Decl::dump() const { 177195341Sed print(llvm::errs()); 178193326Sed} 179193326Sed 180226633Sdimraw_ostream& DeclPrinter::Indent(unsigned Indentation) { 181199990Srdivacky for (unsigned i = 0; i != Indentation; ++i) 182193326Sed Out << " "; 183193326Sed return Out; 184193326Sed} 185193326Sed 186234353Sdimvoid DeclPrinter::prettyPrintAttributes(Decl *D) { 187234353Sdim if (D->hasAttrs()) { 188234353Sdim AttrVec &Attrs = D->getAttrs(); 189234353Sdim for (AttrVec::const_iterator i=Attrs.begin(), e=Attrs.end(); i!=e; ++i) { 190234353Sdim Attr *A = *i; 191234353Sdim A->printPretty(Out, Context); 192234353Sdim } 193234353Sdim } 194234353Sdim} 195234353Sdim 196226633Sdimvoid DeclPrinter::ProcessDeclGroup(SmallVectorImpl<Decl*>& Decls) { 197193326Sed this->Indent(); 198195341Sed Decl::printGroup(Decls.data(), Decls.size(), Out, Policy, Indentation); 199193326Sed Out << ";\n"; 200193326Sed Decls.clear(); 201193326Sed 202193326Sed} 203193326Sed 204198092Srdivackyvoid DeclPrinter::Print(AccessSpecifier AS) { 205198092Srdivacky switch(AS) { 206226633Sdim case AS_none: llvm_unreachable("No access specifier!"); 207198092Srdivacky case AS_public: Out << "public"; break; 208198092Srdivacky case AS_protected: Out << "protected"; break; 209210299Sed case AS_private: Out << "private"; break; 210198092Srdivacky } 211198092Srdivacky} 212198092Srdivacky 213193326Sed//---------------------------------------------------------------------------- 214193326Sed// Common C declarations 215193326Sed//---------------------------------------------------------------------------- 216193326Sed 217193326Sedvoid DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { 218193326Sed if (Indent) 219193326Sed Indentation += Policy.Indentation; 220193326Sed 221226633Sdim SmallVector<Decl*, 2> Decls; 222195341Sed for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end(); 223193326Sed D != DEnd; ++D) { 224212904Sdim 225212904Sdim // Don't print ObjCIvarDecls, as they are printed when visiting the 226212904Sdim // containing ObjCInterfaceDecl. 227212904Sdim if (isa<ObjCIvarDecl>(*D)) 228212904Sdim continue; 229212904Sdim 230193326Sed if (!Policy.Dump) { 231193326Sed // Skip over implicit declarations in pretty-printing mode. 232193326Sed if (D->isImplicit()) continue; 233193326Sed // FIXME: Ugly hack so we don't pretty-print the builtin declaration 234210299Sed // of __builtin_va_list or __[u]int128_t. There should be some other way 235210299Sed // to check that. 236210299Sed if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) { 237210299Sed if (IdentifierInfo *II = ND->getIdentifier()) { 238210299Sed if (II->isStr("__builtin_va_list") || 239210299Sed II->isStr("__int128_t") || II->isStr("__uint128_t")) 240210299Sed continue; 241210299Sed } 242198092Srdivacky } 243198092Srdivacky } 244198092Srdivacky 245193326Sed // The next bits of code handles stuff like "struct {int x;} a,b"; we're 246193326Sed // forced to merge the declarations because there's no other way to 247193326Sed // refer to the struct in question. This limited merging is safe without 248193326Sed // a bunch of other checks because it only merges declarations directly 249193326Sed // referring to the tag, not typedefs. 250193326Sed // 251193326Sed // Check whether the current declaration should be grouped with a previous 252193326Sed // unnamed struct. 253193326Sed QualType CurDeclType = getDeclType(*D); 254193326Sed if (!Decls.empty() && !CurDeclType.isNull()) { 255193326Sed QualType BaseType = GetBaseType(CurDeclType); 256193326Sed if (!BaseType.isNull() && isa<TagType>(BaseType) && 257193326Sed cast<TagType>(BaseType)->getDecl() == Decls[0]) { 258193326Sed Decls.push_back(*D); 259193326Sed continue; 260193326Sed } 261193326Sed } 262193326Sed 263193326Sed // If we have a merged group waiting to be handled, handle it now. 264193326Sed if (!Decls.empty()) 265193326Sed ProcessDeclGroup(Decls); 266193326Sed 267193326Sed // If the current declaration is an unnamed tag type, save it 268193326Sed // so we can merge it with the subsequent declaration(s) using it. 269193326Sed if (isa<TagDecl>(*D) && !cast<TagDecl>(*D)->getIdentifier()) { 270193326Sed Decls.push_back(*D); 271193326Sed continue; 272193326Sed } 273210299Sed 274210299Sed if (isa<AccessSpecDecl>(*D)) { 275210299Sed Indentation -= Policy.Indentation; 276210299Sed this->Indent(); 277210299Sed Print(D->getAccess()); 278210299Sed Out << ":\n"; 279210299Sed Indentation += Policy.Indentation; 280210299Sed continue; 281210299Sed } 282210299Sed 283193326Sed this->Indent(); 284193326Sed Visit(*D); 285198092Srdivacky 286198092Srdivacky // FIXME: Need to be able to tell the DeclPrinter when 287193326Sed const char *Terminator = 0; 288198092Srdivacky if (isa<FunctionDecl>(*D) && 289193326Sed cast<FunctionDecl>(*D)->isThisDeclarationADefinition()) 290193326Sed Terminator = 0; 291193326Sed else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->getBody()) 292193326Sed Terminator = 0; 293193326Sed else if (isa<NamespaceDecl>(*D) || isa<LinkageSpecDecl>(*D) || 294198092Srdivacky isa<ObjCImplementationDecl>(*D) || 295193326Sed isa<ObjCInterfaceDecl>(*D) || 296193326Sed isa<ObjCProtocolDecl>(*D) || 297193326Sed isa<ObjCCategoryImplDecl>(*D) || 298193326Sed isa<ObjCCategoryDecl>(*D)) 299193326Sed Terminator = 0; 300193326Sed else if (isa<EnumConstantDecl>(*D)) { 301193326Sed DeclContext::decl_iterator Next = D; 302193326Sed ++Next; 303193326Sed if (Next != DEnd) 304193326Sed Terminator = ","; 305193326Sed } else 306193326Sed Terminator = ";"; 307193326Sed 308193326Sed if (Terminator) 309193326Sed Out << Terminator; 310193326Sed Out << "\n"; 311193326Sed } 312193326Sed 313193326Sed if (!Decls.empty()) 314193326Sed ProcessDeclGroup(Decls); 315193326Sed 316193326Sed if (Indent) 317193326Sed Indentation -= Policy.Indentation; 318193326Sed} 319193326Sed 320193326Sedvoid DeclPrinter::VisitTranslationUnitDecl(TranslationUnitDecl *D) { 321193326Sed VisitDeclContext(D, false); 322193326Sed} 323193326Sed 324193326Sedvoid DeclPrinter::VisitTypedefDecl(TypedefDecl *D) { 325193326Sed std::string S = D->getNameAsString(); 326193326Sed D->getUnderlyingType().getAsStringInternal(S, Policy); 327226633Sdim if (!Policy.SuppressSpecifiers) { 328193326Sed Out << "typedef "; 329226633Sdim 330226633Sdim if (D->isModulePrivate()) 331226633Sdim Out << "__module_private__ "; 332226633Sdim } 333193326Sed Out << S; 334234353Sdim prettyPrintAttributes(D); 335193326Sed} 336193326Sed 337221345Sdimvoid DeclPrinter::VisitTypeAliasDecl(TypeAliasDecl *D) { 338234353Sdim Out << "using " << *D << " = " << D->getUnderlyingType().getAsString(Policy); 339221345Sdim} 340221345Sdim 341193326Sedvoid DeclPrinter::VisitEnumDecl(EnumDecl *D) { 342226633Sdim if (!Policy.SuppressSpecifiers && D->isModulePrivate()) 343226633Sdim Out << "__module_private__ "; 344218893Sdim Out << "enum "; 345218893Sdim if (D->isScoped()) { 346218893Sdim if (D->isScopedUsingClassTag()) 347218893Sdim Out << "class "; 348218893Sdim else 349218893Sdim Out << "struct "; 350218893Sdim } 351226633Sdim Out << *D; 352218893Sdim 353218893Sdim if (D->isFixed()) { 354218893Sdim std::string Underlying; 355218893Sdim D->getIntegerType().getAsStringInternal(Underlying, Policy); 356218893Sdim Out << " : " << Underlying; 357218893Sdim } 358218893Sdim 359226633Sdim if (D->isCompleteDefinition()) { 360218893Sdim Out << " {\n"; 361218893Sdim VisitDeclContext(D); 362218893Sdim Indent() << "}"; 363218893Sdim } 364234353Sdim prettyPrintAttributes(D); 365193326Sed} 366193326Sed 367193326Sedvoid DeclPrinter::VisitRecordDecl(RecordDecl *D) { 368226633Sdim if (!Policy.SuppressSpecifiers && D->isModulePrivate()) 369226633Sdim Out << "__module_private__ "; 370193326Sed Out << D->getKindName(); 371207619Srdivacky if (D->getIdentifier()) 372226633Sdim Out << ' ' << *D; 373198092Srdivacky 374226633Sdim if (D->isCompleteDefinition()) { 375193326Sed Out << " {\n"; 376193326Sed VisitDeclContext(D); 377193326Sed Indent() << "}"; 378193326Sed } 379193326Sed} 380193326Sed 381193326Sedvoid DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) { 382226633Sdim Out << *D; 383193326Sed if (Expr *Init = D->getInitExpr()) { 384193326Sed Out << " = "; 385193326Sed Init->printPretty(Out, Context, 0, Policy, Indentation); 386193326Sed } 387193326Sed} 388193326Sed 389198092Srdivackyvoid DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { 390193326Sed if (!Policy.SuppressSpecifiers) { 391234353Sdim switch (D->getStorageClassAsWritten()) { 392212904Sdim case SC_None: break; 393212904Sdim case SC_Extern: Out << "extern "; break; 394212904Sdim case SC_Static: Out << "static "; break; 395212904Sdim case SC_PrivateExtern: Out << "__private_extern__ "; break; 396226633Sdim case SC_Auto: case SC_Register: case SC_OpenCLWorkGroupLocal: 397226633Sdim llvm_unreachable("invalid for functions"); 398193326Sed } 399193326Sed 400226633Sdim if (D->isInlineSpecified()) Out << "inline "; 401193326Sed if (D->isVirtualAsWritten()) Out << "virtual "; 402226633Sdim if (D->isModulePrivate()) Out << "__module_private__ "; 403193326Sed } 404193326Sed 405193326Sed PrintingPolicy SubPolicy(Policy); 406193326Sed SubPolicy.SuppressSpecifiers = false; 407212904Sdim std::string Proto = D->getNameInfo().getAsString(); 408193326Sed 409218893Sdim QualType Ty = D->getType(); 410218893Sdim while (const ParenType *PT = dyn_cast<ParenType>(Ty)) { 411218893Sdim Proto = '(' + Proto + ')'; 412218893Sdim Ty = PT->getInnerType(); 413218893Sdim } 414218893Sdim 415218893Sdim if (isa<FunctionType>(Ty)) { 416218893Sdim const FunctionType *AFT = Ty->getAs<FunctionType>(); 417193326Sed const FunctionProtoType *FT = 0; 418193326Sed if (D->hasWrittenPrototype()) 419193326Sed FT = dyn_cast<FunctionProtoType>(AFT); 420193326Sed 421193326Sed Proto += "("; 422193326Sed if (FT) { 423193326Sed llvm::raw_string_ostream POut(Proto); 424193326Sed DeclPrinter ParamPrinter(POut, Context, SubPolicy, Indentation); 425193326Sed for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) { 426193326Sed if (i) POut << ", "; 427193326Sed ParamPrinter.VisitParmVarDecl(D->getParamDecl(i)); 428193326Sed } 429198092Srdivacky 430193326Sed if (FT->isVariadic()) { 431193326Sed if (D->getNumParams()) POut << ", "; 432193326Sed POut << "..."; 433193326Sed } 434223017Sdim } else if (D->doesThisDeclarationHaveABody() && !D->hasPrototype()) { 435193326Sed for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) { 436193326Sed if (i) 437193326Sed Proto += ", "; 438193326Sed Proto += D->getParamDecl(i)->getNameAsString(); 439193326Sed } 440193326Sed } 441193326Sed 442193326Sed Proto += ")"; 443200583Srdivacky 444218893Sdim if (FT && FT->getTypeQuals()) { 445218893Sdim unsigned TypeQuals = FT->getTypeQuals(); 446218893Sdim if (TypeQuals & Qualifiers::Const) 447218893Sdim Proto += " const"; 448218893Sdim if (TypeQuals & Qualifiers::Volatile) 449218893Sdim Proto += " volatile"; 450218893Sdim if (TypeQuals & Qualifiers::Restrict) 451218893Sdim Proto += " restrict"; 452218893Sdim } 453221345Sdim 454221345Sdim if (FT && FT->hasDynamicExceptionSpec()) { 455200583Srdivacky Proto += " throw("; 456221345Sdim if (FT->getExceptionSpecType() == EST_MSAny) 457200583Srdivacky Proto += "..."; 458200583Srdivacky else 459200583Srdivacky for (unsigned I = 0, N = FT->getNumExceptions(); I != N; ++I) { 460200583Srdivacky if (I) 461200583Srdivacky Proto += ", "; 462221345Sdim 463200583Srdivacky std::string ExceptionType; 464200583Srdivacky FT->getExceptionType(I).getAsStringInternal(ExceptionType, SubPolicy); 465200583Srdivacky Proto += ExceptionType; 466200583Srdivacky } 467200583Srdivacky Proto += ")"; 468221345Sdim } else if (FT && isNoexceptExceptionSpec(FT->getExceptionSpecType())) { 469221345Sdim Proto += " noexcept"; 470221345Sdim if (FT->getExceptionSpecType() == EST_ComputedNoexcept) { 471221345Sdim Proto += "("; 472221345Sdim llvm::raw_string_ostream EOut(Proto); 473221345Sdim FT->getNoexceptExpr()->printPretty(EOut, Context, 0, SubPolicy, 474221345Sdim Indentation); 475221345Sdim EOut.flush(); 476221345Sdim Proto += EOut.str(); 477221345Sdim Proto += ")"; 478221345Sdim } 479200583Srdivacky } 480200583Srdivacky 481198092Srdivacky if (CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D)) { 482223017Sdim bool HasInitializerList = false; 483223017Sdim for (CXXConstructorDecl::init_const_iterator B = CDecl->init_begin(), 484223017Sdim E = CDecl->init_end(); 485223017Sdim B != E; ++B) { 486223017Sdim CXXCtorInitializer * BMInitializer = (*B); 487223017Sdim if (BMInitializer->isInClassMemberInitializer()) 488223017Sdim continue; 489223017Sdim 490223017Sdim if (!HasInitializerList) { 491223017Sdim Proto += " : "; 492223017Sdim Out << Proto; 493223017Sdim Proto.clear(); 494223017Sdim HasInitializerList = true; 495223017Sdim } else 496223017Sdim Out << ", "; 497223017Sdim 498223017Sdim if (BMInitializer->isAnyMemberInitializer()) { 499223017Sdim FieldDecl *FD = BMInitializer->getAnyMember(); 500226633Sdim Out << *FD; 501223017Sdim } else { 502226633Sdim Out << QualType(BMInitializer->getBaseClass(), 0).getAsString(Policy); 503223017Sdim } 504223017Sdim 505223017Sdim Out << "("; 506223017Sdim if (!BMInitializer->getInit()) { 507223017Sdim // Nothing to print 508223017Sdim } else { 509223017Sdim Expr *Init = BMInitializer->getInit(); 510223017Sdim if (ExprWithCleanups *Tmp = dyn_cast<ExprWithCleanups>(Init)) 511223017Sdim Init = Tmp->getSubExpr(); 512203955Srdivacky 513223017Sdim Init = Init->IgnoreParens(); 514223017Sdim 515223017Sdim Expr *SimpleInit = 0; 516223017Sdim Expr **Args = 0; 517223017Sdim unsigned NumArgs = 0; 518223017Sdim if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) { 519223017Sdim Args = ParenList->getExprs(); 520223017Sdim NumArgs = ParenList->getNumExprs(); 521223017Sdim } else if (CXXConstructExpr *Construct 522223017Sdim = dyn_cast<CXXConstructExpr>(Init)) { 523223017Sdim Args = Construct->getArgs(); 524223017Sdim NumArgs = Construct->getNumArgs(); 525223017Sdim } else 526223017Sdim SimpleInit = Init; 527223017Sdim 528223017Sdim if (SimpleInit) 529223017Sdim SimpleInit->printPretty(Out, Context, 0, Policy, Indentation); 530223017Sdim else { 531223017Sdim for (unsigned I = 0; I != NumArgs; ++I) { 532223017Sdim if (isa<CXXDefaultArgExpr>(Args[I])) 533223017Sdim break; 534223017Sdim 535223017Sdim if (I) 536223017Sdim Out << ", "; 537223017Sdim Args[I]->printPretty(Out, Context, 0, Policy, Indentation); 538203955Srdivacky } 539198092Srdivacky } 540198092Srdivacky } 541223017Sdim Out << ")"; 542198092Srdivacky } 543198092Srdivacky } 544198092Srdivacky else 545198092Srdivacky AFT->getResultType().getAsStringInternal(Proto, Policy); 546193326Sed } else { 547218893Sdim Ty.getAsStringInternal(Proto, Policy); 548193326Sed } 549193326Sed 550193326Sed Out << Proto; 551234353Sdim prettyPrintAttributes(D); 552193326Sed 553193326Sed if (D->isPure()) 554193326Sed Out << " = 0"; 555223017Sdim else if (D->isDeletedAsWritten()) 556193326Sed Out << " = delete"; 557223017Sdim else if (D->doesThisDeclarationHaveABody()) { 558193326Sed if (!D->hasPrototype() && D->getNumParams()) { 559193326Sed // This is a K&R function definition, so we need to print the 560193326Sed // parameters. 561193326Sed Out << '\n'; 562193326Sed DeclPrinter ParamPrinter(Out, Context, SubPolicy, Indentation); 563193326Sed Indentation += Policy.Indentation; 564193326Sed for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) { 565193326Sed Indent(); 566193326Sed ParamPrinter.VisitParmVarDecl(D->getParamDecl(i)); 567193326Sed Out << ";\n"; 568193326Sed } 569193326Sed Indentation -= Policy.Indentation; 570193326Sed } else 571193326Sed Out << ' '; 572193326Sed 573195341Sed D->getBody()->printPretty(Out, Context, 0, SubPolicy, Indentation); 574193326Sed Out << '\n'; 575193326Sed } 576193326Sed} 577193326Sed 578193326Sedvoid DeclPrinter::VisitFieldDecl(FieldDecl *D) { 579193326Sed if (!Policy.SuppressSpecifiers && D->isMutable()) 580193326Sed Out << "mutable "; 581226633Sdim if (!Policy.SuppressSpecifiers && D->isModulePrivate()) 582226633Sdim Out << "__module_private__ "; 583193326Sed 584193326Sed std::string Name = D->getNameAsString(); 585193326Sed D->getType().getAsStringInternal(Name, Policy); 586193326Sed Out << Name; 587193326Sed 588193326Sed if (D->isBitField()) { 589193326Sed Out << " : "; 590193326Sed D->getBitWidth()->printPretty(Out, Context, 0, Policy, Indentation); 591193326Sed } 592223017Sdim 593223017Sdim Expr *Init = D->getInClassInitializer(); 594223017Sdim if (!Policy.SuppressInitializers && Init) { 595223017Sdim Out << " = "; 596223017Sdim Init->printPretty(Out, Context, 0, Policy, Indentation); 597223017Sdim } 598234353Sdim prettyPrintAttributes(D); 599193326Sed} 600193326Sed 601218893Sdimvoid DeclPrinter::VisitLabelDecl(LabelDecl *D) { 602234353Sdim Out << *D << ":"; 603218893Sdim} 604218893Sdim 605218893Sdim 606193326Sedvoid DeclPrinter::VisitVarDecl(VarDecl *D) { 607234353Sdim StorageClass SCAsWritten = D->getStorageClassAsWritten(); 608234353Sdim if (!Policy.SuppressSpecifiers && SCAsWritten != SC_None) 609234353Sdim Out << VarDecl::getStorageClassSpecifierString(SCAsWritten) << " "; 610193326Sed 611193326Sed if (!Policy.SuppressSpecifiers && D->isThreadSpecified()) 612193326Sed Out << "__thread "; 613226633Sdim if (!Policy.SuppressSpecifiers && D->isModulePrivate()) 614226633Sdim Out << "__module_private__ "; 615193326Sed 616193326Sed std::string Name = D->getNameAsString(); 617193326Sed QualType T = D->getType(); 618198893Srdivacky if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) 619193326Sed T = Parm->getOriginalType(); 620193326Sed T.getAsStringInternal(Name, Policy); 621193326Sed Out << Name; 622221345Sdim Expr *Init = D->getInit(); 623221345Sdim if (!Policy.SuppressInitializers && Init) { 624234353Sdim bool ImplicitInit = false; 625234353Sdim if (CXXConstructExpr *Construct = dyn_cast<CXXConstructExpr>(Init)) 626234353Sdim ImplicitInit = D->getInitStyle() == VarDecl::CallInit && 627234353Sdim Construct->getNumArgs() == 0 && !Construct->isListInitialization(); 628234353Sdim if (!ImplicitInit) { 629234353Sdim if (D->getInitStyle() == VarDecl::CallInit) 630234353Sdim Out << "("; 631234353Sdim else if (D->getInitStyle() == VarDecl::CInit) { 632234353Sdim Out << " = "; 633234353Sdim } 634234353Sdim Init->printPretty(Out, Context, 0, Policy, Indentation); 635234353Sdim if (D->getInitStyle() == VarDecl::CallInit) 636234353Sdim Out << ")"; 637218893Sdim } 638193326Sed } 639234353Sdim prettyPrintAttributes(D); 640193326Sed} 641193326Sed 642193326Sedvoid DeclPrinter::VisitParmVarDecl(ParmVarDecl *D) { 643193326Sed VisitVarDecl(D); 644193326Sed} 645193326Sed 646193326Sedvoid DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) { 647193326Sed Out << "__asm ("; 648193326Sed D->getAsmString()->printPretty(Out, Context, 0, Policy, Indentation); 649193326Sed Out << ")"; 650193326Sed} 651193326Sed 652234353Sdimvoid DeclPrinter::VisitImportDecl(ImportDecl *D) { 653234353Sdim Out << "@__experimental_modules_import " << D->getImportedModule()->getFullModuleName() 654234353Sdim << ";\n"; 655234353Sdim} 656234353Sdim 657221345Sdimvoid DeclPrinter::VisitStaticAssertDecl(StaticAssertDecl *D) { 658221345Sdim Out << "static_assert("; 659221345Sdim D->getAssertExpr()->printPretty(Out, Context, 0, Policy, Indentation); 660221345Sdim Out << ", "; 661221345Sdim D->getMessage()->printPretty(Out, Context, 0, Policy, Indentation); 662221345Sdim Out << ")"; 663221345Sdim} 664221345Sdim 665193326Sed//---------------------------------------------------------------------------- 666193326Sed// C++ declarations 667193326Sed//---------------------------------------------------------------------------- 668193326Sedvoid DeclPrinter::VisitNamespaceDecl(NamespaceDecl *D) { 669226633Sdim Out << "namespace " << *D << " {\n"; 670193326Sed VisitDeclContext(D); 671193326Sed Indent() << "}"; 672193326Sed} 673193326Sed 674193326Sedvoid DeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { 675193326Sed Out << "using namespace "; 676193326Sed if (D->getQualifier()) 677193326Sed D->getQualifier()->print(Out, Policy); 678226633Sdim Out << *D->getNominatedNamespaceAsWritten(); 679193326Sed} 680193326Sed 681193326Sedvoid DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { 682226633Sdim Out << "namespace " << *D << " = "; 683193326Sed if (D->getQualifier()) 684193326Sed D->getQualifier()->print(Out, Policy); 685226633Sdim Out << *D->getAliasedNamespace(); 686193326Sed} 687193326Sed 688193326Sedvoid DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) { 689226633Sdim if (!Policy.SuppressSpecifiers && D->isModulePrivate()) 690226633Sdim Out << "__module_private__ "; 691193326Sed Out << D->getKindName(); 692207619Srdivacky if (D->getIdentifier()) 693226633Sdim Out << ' ' << *D; 694198092Srdivacky 695226633Sdim if (D->isCompleteDefinition()) { 696193326Sed // Print the base classes 697193326Sed if (D->getNumBases()) { 698193326Sed Out << " : "; 699198092Srdivacky for (CXXRecordDecl::base_class_iterator Base = D->bases_begin(), 700198092Srdivacky BaseEnd = D->bases_end(); Base != BaseEnd; ++Base) { 701193326Sed if (Base != D->bases_begin()) 702193326Sed Out << ", "; 703193326Sed 704193326Sed if (Base->isVirtual()) 705193326Sed Out << "virtual "; 706193326Sed 707198092Srdivacky AccessSpecifier AS = Base->getAccessSpecifierAsWritten(); 708198092Srdivacky if (AS != AS_none) 709198092Srdivacky Print(AS); 710198092Srdivacky Out << " " << Base->getType().getAsString(Policy); 711221345Sdim 712221345Sdim if (Base->isPackExpansion()) 713221345Sdim Out << "..."; 714193326Sed } 715193326Sed } 716193326Sed 717193326Sed // Print the class definition 718193326Sed // FIXME: Doesn't print access specifiers, e.g., "public:" 719193326Sed Out << " {\n"; 720193326Sed VisitDeclContext(D); 721193326Sed Indent() << "}"; 722198092Srdivacky } 723193326Sed} 724193326Sed 725193326Sedvoid DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) { 726193326Sed const char *l; 727193326Sed if (D->getLanguage() == LinkageSpecDecl::lang_c) 728193326Sed l = "C"; 729193326Sed else { 730193326Sed assert(D->getLanguage() == LinkageSpecDecl::lang_cxx && 731193326Sed "unknown language in linkage specification"); 732193326Sed l = "C++"; 733193326Sed } 734193326Sed 735193326Sed Out << "extern \"" << l << "\" "; 736193326Sed if (D->hasBraces()) { 737193326Sed Out << "{\n"; 738193326Sed VisitDeclContext(D); 739193326Sed Indent() << "}"; 740193326Sed } else 741195341Sed Visit(*D->decls_begin()); 742193326Sed} 743193326Sed 744226633Sdimvoid DeclPrinter::PrintTemplateParameters( 745226633Sdim const TemplateParameterList *Params, const TemplateArgumentList *Args = 0) { 746226633Sdim assert(Params); 747226633Sdim assert(!Args || Params->size() == Args->size()); 748226633Sdim 749193576Sed Out << "template <"; 750198092Srdivacky 751193576Sed for (unsigned i = 0, e = Params->size(); i != e; ++i) { 752193576Sed if (i != 0) 753193576Sed Out << ", "; 754198092Srdivacky 755193576Sed const Decl *Param = Params->getParam(i); 756198092Srdivacky if (const TemplateTypeParmDecl *TTP = 757193576Sed dyn_cast<TemplateTypeParmDecl>(Param)) { 758198092Srdivacky 759193576Sed if (TTP->wasDeclaredWithTypename()) 760193576Sed Out << "typename "; 761193576Sed else 762193576Sed Out << "class "; 763193576Sed 764194179Sed if (TTP->isParameterPack()) 765194179Sed Out << "... "; 766198092Srdivacky 767234353Sdim Out << *TTP; 768193576Sed 769226633Sdim if (Args) { 770193576Sed Out << " = "; 771226633Sdim Args->get(i).print(Policy, Out); 772226633Sdim } else if (TTP->hasDefaultArgument()) { 773226633Sdim Out << " = "; 774193576Sed Out << TTP->getDefaultArgument().getAsString(Policy); 775193576Sed }; 776198092Srdivacky } else if (const NonTypeTemplateParmDecl *NTTP = 777193576Sed dyn_cast<NonTypeTemplateParmDecl>(Param)) { 778193576Sed Out << NTTP->getType().getAsString(Policy); 779193576Sed 780218893Sdim if (NTTP->isParameterPack() && !isa<PackExpansionType>(NTTP->getType())) 781218893Sdim Out << "..."; 782218893Sdim 783193576Sed if (IdentifierInfo *Name = NTTP->getIdentifier()) { 784193576Sed Out << ' '; 785193576Sed Out << Name->getName(); 786193576Sed } 787198092Srdivacky 788226633Sdim if (Args) { 789193576Sed Out << " = "; 790226633Sdim Args->get(i).print(Policy, Out); 791226633Sdim } else if (NTTP->hasDefaultArgument()) { 792226633Sdim Out << " = "; 793198092Srdivacky NTTP->getDefaultArgument()->printPretty(Out, Context, 0, Policy, 794193576Sed Indentation); 795193576Sed } 796221345Sdim } else if (const TemplateTemplateParmDecl *TTPD = 797221345Sdim dyn_cast<TemplateTemplateParmDecl>(Param)) { 798221345Sdim VisitTemplateDecl(TTPD); 799221345Sdim // FIXME: print the default argument, if present. 800193576Sed } 801193576Sed } 802198092Srdivacky 803193576Sed Out << "> "; 804226633Sdim} 805193576Sed 806226633Sdimvoid DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) { 807226633Sdim PrintTemplateParameters(D->getTemplateParameters()); 808226633Sdim 809221345Sdim if (const TemplateTemplateParmDecl *TTP = 810221345Sdim dyn_cast<TemplateTemplateParmDecl>(D)) { 811218893Sdim Out << "class "; 812218893Sdim if (TTP->isParameterPack()) 813218893Sdim Out << "..."; 814218893Sdim Out << D->getName(); 815210299Sed } else { 816210299Sed Visit(D->getTemplatedDecl()); 817210299Sed } 818193326Sed} 819193326Sed 820226633Sdimvoid DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { 821226633Sdim if (PrintInstantiation) { 822226633Sdim TemplateParameterList *Params = D->getTemplateParameters(); 823226633Sdim for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(), E = D->spec_end(); 824226633Sdim I != E; ++I) { 825226633Sdim PrintTemplateParameters(Params, (*I)->getTemplateSpecializationArgs()); 826226633Sdim Visit(*I); 827226633Sdim } 828226633Sdim } 829226633Sdim 830226633Sdim return VisitRedeclarableTemplateDecl(D); 831226633Sdim} 832226633Sdim 833226633Sdimvoid DeclPrinter::VisitClassTemplateDecl(ClassTemplateDecl *D) { 834226633Sdim if (PrintInstantiation) { 835226633Sdim TemplateParameterList *Params = D->getTemplateParameters(); 836226633Sdim for (ClassTemplateDecl::spec_iterator I = D->spec_begin(), E = D->spec_end(); 837226633Sdim I != E; ++I) { 838226633Sdim PrintTemplateParameters(Params, &(*I)->getTemplateArgs()); 839226633Sdim Visit(*I); 840226633Sdim Out << '\n'; 841226633Sdim } 842226633Sdim } 843226633Sdim 844226633Sdim return VisitRedeclarableTemplateDecl(D); 845226633Sdim} 846226633Sdim 847193326Sed//---------------------------------------------------------------------------- 848193326Sed// Objective-C declarations 849193326Sed//---------------------------------------------------------------------------- 850193326Sed 851193326Sedvoid DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) { 852193326Sed if (OMD->isInstanceMethod()) 853193326Sed Out << "- "; 854198092Srdivacky else 855193326Sed Out << "+ "; 856193326Sed if (!OMD->getResultType().isNull()) 857193326Sed Out << '(' << OMD->getResultType().getAsString(Policy) << ")"; 858198092Srdivacky 859193326Sed std::string name = OMD->getSelector().getAsString(); 860193326Sed std::string::size_type pos, lastPos = 0; 861193326Sed for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(), 862193326Sed E = OMD->param_end(); PI != E; ++PI) { 863198092Srdivacky // FIXME: selector is missing here! 864226633Sdim pos = name.find_first_of(':', lastPos); 865193326Sed Out << " " << name.substr(lastPos, pos - lastPos); 866226633Sdim Out << ":(" << (*PI)->getType().getAsString(Policy) << ')' << **PI; 867193326Sed lastPos = pos + 1; 868193326Sed } 869198092Srdivacky 870193326Sed if (OMD->param_begin() == OMD->param_end()) 871193326Sed Out << " " << name; 872198092Srdivacky 873193326Sed if (OMD->isVariadic()) 874193326Sed Out << ", ..."; 875198092Srdivacky 876193326Sed if (OMD->getBody()) { 877193326Sed Out << ' '; 878193326Sed OMD->getBody()->printPretty(Out, Context, 0, Policy); 879193326Sed Out << '\n'; 880193326Sed } 881193326Sed} 882193326Sed 883193326Sedvoid DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) { 884193326Sed std::string I = OID->getNameAsString(); 885193326Sed ObjCInterfaceDecl *SID = OID->getSuperClass(); 886193326Sed 887193326Sed if (SID) 888226633Sdim Out << "@implementation " << I << " : " << *SID; 889193326Sed else 890193326Sed Out << "@implementation " << I; 891193326Sed Out << "\n"; 892193326Sed VisitDeclContext(OID, false); 893193326Sed Out << "@end"; 894193326Sed} 895193326Sed 896193326Sedvoid DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) { 897193326Sed std::string I = OID->getNameAsString(); 898193326Sed ObjCInterfaceDecl *SID = OID->getSuperClass(); 899193326Sed 900234353Sdim if (!OID->isThisDeclarationADefinition()) { 901234353Sdim Out << "@class " << I << ";"; 902234353Sdim return; 903234353Sdim } 904234353Sdim 905193326Sed if (SID) 906226633Sdim Out << "@interface " << I << " : " << *SID; 907193326Sed else 908193326Sed Out << "@interface " << I; 909198092Srdivacky 910193326Sed // Protocols? 911193326Sed const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols(); 912193326Sed if (!Protocols.empty()) { 913193326Sed for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 914193326Sed E = Protocols.end(); I != E; ++I) 915226633Sdim Out << (I == Protocols.begin() ? '<' : ',') << **I; 916193326Sed } 917198092Srdivacky 918193326Sed if (!Protocols.empty()) 919193326Sed Out << "> "; 920198092Srdivacky 921193326Sed if (OID->ivar_size() > 0) { 922193326Sed Out << "{\n"; 923193326Sed Indentation += Policy.Indentation; 924193326Sed for (ObjCInterfaceDecl::ivar_iterator I = OID->ivar_begin(), 925193326Sed E = OID->ivar_end(); I != E; ++I) { 926226633Sdim Indent() << (*I)->getType().getAsString(Policy) << ' ' << **I << ";\n"; 927193326Sed } 928193326Sed Indentation -= Policy.Indentation; 929193326Sed Out << "}\n"; 930193326Sed } 931198092Srdivacky 932193326Sed VisitDeclContext(OID, false); 933193326Sed Out << "@end"; 934193326Sed // FIXME: implement the rest... 935193326Sed} 936193326Sed 937234353Sdimvoid DeclPrinter::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) { 938234353Sdim if (!PID->isThisDeclarationADefinition()) { 939234353Sdim Out << "@protocol " << PID->getIdentifier() << ";\n"; 940234353Sdim return; 941193326Sed } 942234353Sdim 943226633Sdim Out << "@protocol " << *PID << '\n'; 944193326Sed VisitDeclContext(PID, false); 945193326Sed Out << "@end"; 946193326Sed} 947193326Sed 948193326Sedvoid DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) { 949226633Sdim Out << "@implementation " << *PID->getClassInterface() << '(' << *PID <<")\n"; 950193326Sed 951193326Sed VisitDeclContext(PID, false); 952193326Sed Out << "@end"; 953193326Sed // FIXME: implement the rest... 954193326Sed} 955193326Sed 956193326Sedvoid DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) { 957226633Sdim Out << "@interface " << *PID->getClassInterface() << '(' << *PID << ")\n"; 958193326Sed VisitDeclContext(PID, false); 959193326Sed Out << "@end"; 960198092Srdivacky 961193326Sed // FIXME: implement the rest... 962193326Sed} 963193326Sed 964193326Sedvoid DeclPrinter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID) { 965226633Sdim Out << "@compatibility_alias " << *AID 966226633Sdim << ' ' << *AID->getClassInterface() << ";\n"; 967193326Sed} 968193326Sed 969193326Sed/// PrintObjCPropertyDecl - print a property declaration. 970193326Sed/// 971193326Sedvoid DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) { 972193326Sed if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Required) 973193326Sed Out << "@required\n"; 974193326Sed else if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Optional) 975193326Sed Out << "@optional\n"; 976198092Srdivacky 977193326Sed Out << "@property"; 978193326Sed if (PDecl->getPropertyAttributes() != ObjCPropertyDecl::OBJC_PR_noattr) { 979193326Sed bool first = true; 980193326Sed Out << " ("; 981198092Srdivacky if (PDecl->getPropertyAttributes() & 982193326Sed ObjCPropertyDecl::OBJC_PR_readonly) { 983193326Sed Out << (first ? ' ' : ',') << "readonly"; 984193326Sed first = false; 985226633Sdim } 986198092Srdivacky 987226633Sdim if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) { 988226633Sdim Out << (first ? ' ' : ',') << "getter = " 989226633Sdim << PDecl->getGetterName().getAsString(); 990226633Sdim first = false; 991226633Sdim } 992226633Sdim if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) { 993226633Sdim Out << (first ? ' ' : ',') << "setter = " 994226633Sdim << PDecl->getSetterName().getAsString(); 995226633Sdim first = false; 996226633Sdim } 997198092Srdivacky 998226633Sdim if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_assign) { 999226633Sdim Out << (first ? ' ' : ',') << "assign"; 1000226633Sdim first = false; 1001226633Sdim } 1002198092Srdivacky 1003226633Sdim if (PDecl->getPropertyAttributes() & 1004226633Sdim ObjCPropertyDecl::OBJC_PR_readwrite) { 1005226633Sdim Out << (first ? ' ' : ',') << "readwrite"; 1006226633Sdim first = false; 1007226633Sdim } 1008198092Srdivacky 1009226633Sdim if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) { 1010226633Sdim Out << (first ? ' ' : ',') << "retain"; 1011226633Sdim first = false; 1012226633Sdim } 1013198092Srdivacky 1014226633Sdim if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_strong) { 1015226633Sdim Out << (first ? ' ' : ',') << "strong"; 1016226633Sdim first = false; 1017226633Sdim } 1018224145Sdim 1019226633Sdim if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) { 1020226633Sdim Out << (first ? ' ' : ',') << "copy"; 1021226633Sdim first = false; 1022226633Sdim } 1023198092Srdivacky 1024226633Sdim if (PDecl->getPropertyAttributes() & 1025226633Sdim ObjCPropertyDecl::OBJC_PR_nonatomic) { 1026226633Sdim Out << (first ? ' ' : ',') << "nonatomic"; 1027226633Sdim first = false; 1028226633Sdim } 1029226633Sdim if (PDecl->getPropertyAttributes() & 1030226633Sdim ObjCPropertyDecl::OBJC_PR_atomic) { 1031226633Sdim Out << (first ? ' ' : ',') << "atomic"; 1032226633Sdim first = false; 1033226633Sdim } 1034226633Sdim 1035226633Sdim (void) first; // Silence dead store warning due to idiomatic code. 1036226633Sdim Out << " )"; 1037193326Sed } 1038226633Sdim Out << ' ' << PDecl->getType().getAsString(Policy) << ' ' << *PDecl; 1039193326Sed} 1040193326Sed 1041193326Sedvoid DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) { 1042193326Sed if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) 1043193326Sed Out << "@synthesize "; 1044193326Sed else 1045193326Sed Out << "@dynamic "; 1046226633Sdim Out << *PID->getPropertyDecl(); 1047193326Sed if (PID->getPropertyIvarDecl()) 1048226633Sdim Out << '=' << *PID->getPropertyIvarDecl(); 1049193326Sed} 1050198092Srdivacky 1051198092Srdivackyvoid DeclPrinter::VisitUsingDecl(UsingDecl *D) { 1052198092Srdivacky Out << "using "; 1053219077Sdim D->getQualifier()->print(Out, Policy); 1054226633Sdim Out << *D; 1055198092Srdivacky} 1056198092Srdivacky 1057199482Srdivackyvoid 1058199482SrdivackyDeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { 1059199482Srdivacky Out << "using typename "; 1060219077Sdim D->getQualifier()->print(Out, Policy); 1061207619Srdivacky Out << D->getDeclName(); 1062199482Srdivacky} 1063199482Srdivacky 1064199482Srdivackyvoid DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { 1065198092Srdivacky Out << "using "; 1066219077Sdim D->getQualifier()->print(Out, Policy); 1067207619Srdivacky Out << D->getDeclName(); 1068198092Srdivacky} 1069199482Srdivacky 1070199482Srdivackyvoid DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) { 1071199482Srdivacky // ignore 1072199482Srdivacky} 1073