DeclPrinter.cpp revision 249423
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// 10249423Sdim// This file implements the Decl::print method, which pretty prints the 11193326Sed// AST back out to C/Objective-C/C++/Objective-C++ code. 12193326Sed// 13193326Sed//===----------------------------------------------------------------------===// 14193326Sed#include "clang/AST/ASTContext.h" 15249423Sdim#include "clang/AST/Attr.h" 16193326Sed#include "clang/AST/Decl.h" 17193326Sed#include "clang/AST/DeclCXX.h" 18193326Sed#include "clang/AST/DeclObjC.h" 19249423Sdim#include "clang/AST/DeclVisitor.h" 20193326Sed#include "clang/AST/Expr.h" 21203955Srdivacky#include "clang/AST/ExprCXX.h" 22193326Sed#include "clang/AST/PrettyPrinter.h" 23234353Sdim#include "clang/Basic/Module.h" 24193326Sed#include "llvm/Support/raw_ostream.h" 25193326Sedusing namespace clang; 26193326Sed 27193326Sednamespace { 28199990Srdivacky class DeclPrinter : public DeclVisitor<DeclPrinter> { 29226633Sdim raw_ostream &Out; 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: 41239462Sdim DeclPrinter(raw_ostream &Out, const PrintingPolicy &Policy, 42239462Sdim unsigned Indentation = 0, bool PrintInstantiation = false) 43239462Sdim : Out(Out), Policy(Policy), Indentation(Indentation), 44226633Sdim PrintInstantiation(PrintInstantiation) { } 45193326Sed 46193326Sed void VisitDeclContext(DeclContext *DC, bool Indent = true); 47193326Sed 48193326Sed void VisitTranslationUnitDecl(TranslationUnitDecl *D); 49193326Sed void VisitTypedefDecl(TypedefDecl *D); 50221345Sdim void VisitTypeAliasDecl(TypeAliasDecl *D); 51193326Sed void VisitEnumDecl(EnumDecl *D); 52193326Sed void VisitRecordDecl(RecordDecl *D); 53193326Sed void VisitEnumConstantDecl(EnumConstantDecl *D); 54249423Sdim void VisitEmptyDecl(EmptyDecl *D); 55193326Sed void VisitFunctionDecl(FunctionDecl *D); 56249423Sdim void VisitFriendDecl(FriendDecl *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); 85249423Sdim void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D); 86226633Sdim 87226633Sdim void PrintTemplateParameters(const TemplateParameterList *Params, 88249423Sdim const TemplateArgumentList *Args = 0); 89234353Sdim void prettyPrintAttributes(Decl *D); 90193326Sed }; 91193326Sed} 92193326Sed 93226633Sdimvoid Decl::print(raw_ostream &Out, unsigned Indentation, 94226633Sdim bool PrintInstantiation) const { 95226633Sdim print(Out, getASTContext().getPrintingPolicy(), Indentation, PrintInstantiation); 96193326Sed} 97193326Sed 98226633Sdimvoid Decl::print(raw_ostream &Out, const PrintingPolicy &Policy, 99226633Sdim unsigned Indentation, bool PrintInstantiation) const { 100239462Sdim DeclPrinter Printer(Out, Policy, Indentation, PrintInstantiation); 101198092Srdivacky Printer.Visit(const_cast<Decl*>(this)); 102193326Sed} 103193326Sed 104193326Sedstatic QualType GetBaseType(QualType T) { 105193326Sed // FIXME: This should be on the Type class! 106193326Sed QualType BaseType = T; 107193326Sed while (!BaseType->isSpecifierType()) { 108193326Sed if (isa<TypedefType>(BaseType)) 109193326Sed break; 110198092Srdivacky else if (const PointerType* PTy = BaseType->getAs<PointerType>()) 111193326Sed BaseType = PTy->getPointeeType(); 112243830Sdim else if (const BlockPointerType *BPy = BaseType->getAs<BlockPointerType>()) 113243830Sdim BaseType = BPy->getPointeeType(); 114193326Sed else if (const ArrayType* ATy = dyn_cast<ArrayType>(BaseType)) 115193326Sed BaseType = ATy->getElementType(); 116198092Srdivacky else if (const FunctionType* FTy = BaseType->getAs<FunctionType>()) 117193326Sed BaseType = FTy->getResultType(); 118198092Srdivacky else if (const VectorType *VTy = BaseType->getAs<VectorType>()) 119195341Sed BaseType = VTy->getElementType(); 120239462Sdim else if (const ReferenceType *RTy = BaseType->getAs<ReferenceType>()) 121239462Sdim BaseType = RTy->getPointeeType(); 122193326Sed else 123226633Sdim llvm_unreachable("Unknown declarator!"); 124193326Sed } 125193326Sed return BaseType; 126193326Sed} 127193326Sed 128193326Sedstatic QualType getDeclType(Decl* D) { 129221345Sdim if (TypedefNameDecl* TDD = dyn_cast<TypedefNameDecl>(D)) 130193326Sed return TDD->getUnderlyingType(); 131193326Sed if (ValueDecl* VD = dyn_cast<ValueDecl>(D)) 132193326Sed return VD->getType(); 133193326Sed return QualType(); 134193326Sed} 135193326Sed 136193326Sedvoid Decl::printGroup(Decl** Begin, unsigned NumDecls, 137226633Sdim raw_ostream &Out, const PrintingPolicy &Policy, 138193326Sed unsigned Indentation) { 139193326Sed if (NumDecls == 1) { 140195341Sed (*Begin)->print(Out, Policy, Indentation); 141193326Sed return; 142193326Sed } 143193326Sed 144193326Sed Decl** End = Begin + NumDecls; 145193326Sed TagDecl* TD = dyn_cast<TagDecl>(*Begin); 146193326Sed if (TD) 147193326Sed ++Begin; 148193326Sed 149193326Sed PrintingPolicy SubPolicy(Policy); 150226633Sdim if (TD && TD->isCompleteDefinition()) { 151195341Sed TD->print(Out, Policy, Indentation); 152193326Sed Out << " "; 153193326Sed SubPolicy.SuppressTag = true; 154193326Sed } 155193326Sed 156193326Sed bool isFirst = true; 157193326Sed for ( ; Begin != End; ++Begin) { 158193326Sed if (isFirst) { 159193326Sed SubPolicy.SuppressSpecifiers = false; 160193326Sed isFirst = false; 161193326Sed } else { 162193326Sed if (!isFirst) Out << ", "; 163193326Sed SubPolicy.SuppressSpecifiers = true; 164193326Sed } 165193326Sed 166195341Sed (*Begin)->print(Out, SubPolicy, Indentation); 167193326Sed } 168193326Sed} 169193326Sed 170200583Srdivackyvoid DeclContext::dumpDeclContext() const { 171200583Srdivacky // Get the translation unit 172200583Srdivacky const DeclContext *DC = this; 173200583Srdivacky while (!DC->isTranslationUnit()) 174200583Srdivacky DC = DC->getParent(); 175200583Srdivacky 176200583Srdivacky ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext(); 177239462Sdim DeclPrinter Printer(llvm::errs(), Ctx.getPrintingPolicy(), 0); 178200583Srdivacky Printer.VisitDeclContext(const_cast<DeclContext *>(this), /*Indent=*/false); 179200583Srdivacky} 180200583Srdivacky 181226633Sdimraw_ostream& DeclPrinter::Indent(unsigned Indentation) { 182199990Srdivacky for (unsigned i = 0; i != Indentation; ++i) 183193326Sed Out << " "; 184193326Sed return Out; 185193326Sed} 186193326Sed 187234353Sdimvoid DeclPrinter::prettyPrintAttributes(Decl *D) { 188249423Sdim if (Policy.PolishForDeclaration) 189243830Sdim return; 190243830Sdim 191234353Sdim if (D->hasAttrs()) { 192234353Sdim AttrVec &Attrs = D->getAttrs(); 193234353Sdim for (AttrVec::const_iterator i=Attrs.begin(), e=Attrs.end(); i!=e; ++i) { 194239462Sdim Attr *A = *i; 195239462Sdim A->printPretty(Out, Policy); 196234353Sdim } 197234353Sdim } 198234353Sdim} 199234353Sdim 200226633Sdimvoid DeclPrinter::ProcessDeclGroup(SmallVectorImpl<Decl*>& Decls) { 201193326Sed this->Indent(); 202195341Sed Decl::printGroup(Decls.data(), Decls.size(), Out, Policy, Indentation); 203193326Sed Out << ";\n"; 204193326Sed Decls.clear(); 205193326Sed 206193326Sed} 207193326Sed 208198092Srdivackyvoid DeclPrinter::Print(AccessSpecifier AS) { 209198092Srdivacky switch(AS) { 210226633Sdim case AS_none: llvm_unreachable("No access specifier!"); 211198092Srdivacky case AS_public: Out << "public"; break; 212198092Srdivacky case AS_protected: Out << "protected"; break; 213210299Sed case AS_private: Out << "private"; break; 214198092Srdivacky } 215198092Srdivacky} 216198092Srdivacky 217193326Sed//---------------------------------------------------------------------------- 218193326Sed// Common C declarations 219193326Sed//---------------------------------------------------------------------------- 220193326Sed 221193326Sedvoid DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) { 222243830Sdim if (Policy.TerseOutput) 223243830Sdim return; 224243830Sdim 225193326Sed if (Indent) 226193326Sed Indentation += Policy.Indentation; 227193326Sed 228226633Sdim SmallVector<Decl*, 2> Decls; 229195341Sed for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end(); 230193326Sed D != DEnd; ++D) { 231212904Sdim 232212904Sdim // Don't print ObjCIvarDecls, as they are printed when visiting the 233212904Sdim // containing ObjCInterfaceDecl. 234212904Sdim if (isa<ObjCIvarDecl>(*D)) 235212904Sdim continue; 236212904Sdim 237249423Sdim // Skip over implicit declarations in pretty-printing mode. 238249423Sdim if (D->isImplicit()) 239249423Sdim continue; 240249423Sdim 241249423Sdim // FIXME: Ugly hack so we don't pretty-print the builtin declaration 242249423Sdim // of __builtin_va_list or __[u]int128_t. There should be some other way 243249423Sdim // to check that. 244249423Sdim if (NamedDecl *ND = dyn_cast<NamedDecl>(*D)) { 245249423Sdim if (IdentifierInfo *II = ND->getIdentifier()) { 246249423Sdim if (II->isStr("__builtin_va_list") || 247249423Sdim II->isStr("__int128_t") || II->isStr("__uint128_t")) 248249423Sdim continue; 249198092Srdivacky } 250198092Srdivacky } 251198092Srdivacky 252193326Sed // The next bits of code handles stuff like "struct {int x;} a,b"; we're 253193326Sed // forced to merge the declarations because there's no other way to 254193326Sed // refer to the struct in question. This limited merging is safe without 255193326Sed // a bunch of other checks because it only merges declarations directly 256193326Sed // referring to the tag, not typedefs. 257193326Sed // 258193326Sed // Check whether the current declaration should be grouped with a previous 259193326Sed // unnamed struct. 260193326Sed QualType CurDeclType = getDeclType(*D); 261193326Sed if (!Decls.empty() && !CurDeclType.isNull()) { 262193326Sed QualType BaseType = GetBaseType(CurDeclType); 263193326Sed if (!BaseType.isNull() && isa<TagType>(BaseType) && 264193326Sed cast<TagType>(BaseType)->getDecl() == Decls[0]) { 265193326Sed Decls.push_back(*D); 266193326Sed continue; 267193326Sed } 268193326Sed } 269193326Sed 270193326Sed // If we have a merged group waiting to be handled, handle it now. 271193326Sed if (!Decls.empty()) 272193326Sed ProcessDeclGroup(Decls); 273193326Sed 274193326Sed // If the current declaration is an unnamed tag type, save it 275193326Sed // so we can merge it with the subsequent declaration(s) using it. 276193326Sed if (isa<TagDecl>(*D) && !cast<TagDecl>(*D)->getIdentifier()) { 277193326Sed Decls.push_back(*D); 278193326Sed continue; 279193326Sed } 280210299Sed 281210299Sed if (isa<AccessSpecDecl>(*D)) { 282210299Sed Indentation -= Policy.Indentation; 283210299Sed this->Indent(); 284210299Sed Print(D->getAccess()); 285210299Sed Out << ":\n"; 286210299Sed Indentation += Policy.Indentation; 287210299Sed continue; 288210299Sed } 289210299Sed 290193326Sed this->Indent(); 291193326Sed Visit(*D); 292198092Srdivacky 293198092Srdivacky // FIXME: Need to be able to tell the DeclPrinter when 294193326Sed const char *Terminator = 0; 295249423Sdim if (isa<OMPThreadPrivateDecl>(*D)) 296193326Sed Terminator = 0; 297249423Sdim else if (isa<FunctionDecl>(*D) && 298249423Sdim cast<FunctionDecl>(*D)->isThisDeclarationADefinition()) 299249423Sdim Terminator = 0; 300193326Sed else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->getBody()) 301193326Sed Terminator = 0; 302193326Sed else if (isa<NamespaceDecl>(*D) || isa<LinkageSpecDecl>(*D) || 303198092Srdivacky isa<ObjCImplementationDecl>(*D) || 304193326Sed isa<ObjCInterfaceDecl>(*D) || 305193326Sed isa<ObjCProtocolDecl>(*D) || 306193326Sed isa<ObjCCategoryImplDecl>(*D) || 307193326Sed isa<ObjCCategoryDecl>(*D)) 308193326Sed Terminator = 0; 309193326Sed else if (isa<EnumConstantDecl>(*D)) { 310193326Sed DeclContext::decl_iterator Next = D; 311193326Sed ++Next; 312193326Sed if (Next != DEnd) 313193326Sed Terminator = ","; 314193326Sed } else 315193326Sed Terminator = ";"; 316193326Sed 317193326Sed if (Terminator) 318193326Sed Out << Terminator; 319193326Sed Out << "\n"; 320193326Sed } 321193326Sed 322193326Sed if (!Decls.empty()) 323193326Sed ProcessDeclGroup(Decls); 324193326Sed 325193326Sed if (Indent) 326193326Sed Indentation -= Policy.Indentation; 327193326Sed} 328193326Sed 329193326Sedvoid DeclPrinter::VisitTranslationUnitDecl(TranslationUnitDecl *D) { 330193326Sed VisitDeclContext(D, false); 331193326Sed} 332193326Sed 333193326Sedvoid DeclPrinter::VisitTypedefDecl(TypedefDecl *D) { 334226633Sdim if (!Policy.SuppressSpecifiers) { 335193326Sed Out << "typedef "; 336226633Sdim 337226633Sdim if (D->isModulePrivate()) 338226633Sdim Out << "__module_private__ "; 339226633Sdim } 340239462Sdim D->getUnderlyingType().print(Out, Policy, D->getName()); 341234353Sdim prettyPrintAttributes(D); 342193326Sed} 343193326Sed 344221345Sdimvoid DeclPrinter::VisitTypeAliasDecl(TypeAliasDecl *D) { 345234353Sdim Out << "using " << *D << " = " << D->getUnderlyingType().getAsString(Policy); 346221345Sdim} 347221345Sdim 348193326Sedvoid DeclPrinter::VisitEnumDecl(EnumDecl *D) { 349226633Sdim if (!Policy.SuppressSpecifiers && D->isModulePrivate()) 350226633Sdim Out << "__module_private__ "; 351218893Sdim Out << "enum "; 352218893Sdim if (D->isScoped()) { 353218893Sdim if (D->isScopedUsingClassTag()) 354218893Sdim Out << "class "; 355218893Sdim else 356218893Sdim Out << "struct "; 357218893Sdim } 358226633Sdim Out << *D; 359218893Sdim 360239462Sdim if (D->isFixed()) 361239462Sdim Out << " : " << D->getIntegerType().stream(Policy); 362218893Sdim 363226633Sdim if (D->isCompleteDefinition()) { 364218893Sdim Out << " {\n"; 365218893Sdim VisitDeclContext(D); 366218893Sdim Indent() << "}"; 367218893Sdim } 368234353Sdim prettyPrintAttributes(D); 369193326Sed} 370193326Sed 371193326Sedvoid DeclPrinter::VisitRecordDecl(RecordDecl *D) { 372226633Sdim if (!Policy.SuppressSpecifiers && D->isModulePrivate()) 373226633Sdim Out << "__module_private__ "; 374193326Sed Out << D->getKindName(); 375207619Srdivacky if (D->getIdentifier()) 376226633Sdim Out << ' ' << *D; 377198092Srdivacky 378226633Sdim if (D->isCompleteDefinition()) { 379193326Sed Out << " {\n"; 380193326Sed VisitDeclContext(D); 381193326Sed Indent() << "}"; 382193326Sed } 383193326Sed} 384193326Sed 385193326Sedvoid DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) { 386226633Sdim Out << *D; 387193326Sed if (Expr *Init = D->getInitExpr()) { 388193326Sed Out << " = "; 389239462Sdim Init->printPretty(Out, 0, Policy, Indentation); 390193326Sed } 391193326Sed} 392193326Sed 393198092Srdivackyvoid DeclPrinter::VisitFunctionDecl(FunctionDecl *D) { 394249423Sdim CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D); 395193326Sed if (!Policy.SuppressSpecifiers) { 396249423Sdim switch (D->getStorageClass()) { 397212904Sdim case SC_None: break; 398212904Sdim case SC_Extern: Out << "extern "; break; 399212904Sdim case SC_Static: Out << "static "; break; 400212904Sdim case SC_PrivateExtern: Out << "__private_extern__ "; break; 401226633Sdim case SC_Auto: case SC_Register: case SC_OpenCLWorkGroupLocal: 402226633Sdim llvm_unreachable("invalid for functions"); 403193326Sed } 404193326Sed 405226633Sdim if (D->isInlineSpecified()) Out << "inline "; 406193326Sed if (D->isVirtualAsWritten()) Out << "virtual "; 407226633Sdim if (D->isModulePrivate()) Out << "__module_private__ "; 408249423Sdim if (CDecl && CDecl->isExplicitSpecified()) 409249423Sdim Out << "explicit "; 410193326Sed } 411193326Sed 412193326Sed PrintingPolicy SubPolicy(Policy); 413193326Sed SubPolicy.SuppressSpecifiers = false; 414212904Sdim std::string Proto = D->getNameInfo().getAsString(); 415193326Sed 416218893Sdim QualType Ty = D->getType(); 417218893Sdim while (const ParenType *PT = dyn_cast<ParenType>(Ty)) { 418218893Sdim Proto = '(' + Proto + ')'; 419218893Sdim Ty = PT->getInnerType(); 420218893Sdim } 421218893Sdim 422218893Sdim if (isa<FunctionType>(Ty)) { 423218893Sdim const FunctionType *AFT = Ty->getAs<FunctionType>(); 424193326Sed const FunctionProtoType *FT = 0; 425193326Sed if (D->hasWrittenPrototype()) 426193326Sed FT = dyn_cast<FunctionProtoType>(AFT); 427193326Sed 428193326Sed Proto += "("; 429193326Sed if (FT) { 430193326Sed llvm::raw_string_ostream POut(Proto); 431239462Sdim DeclPrinter ParamPrinter(POut, SubPolicy, Indentation); 432193326Sed for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) { 433193326Sed if (i) POut << ", "; 434193326Sed ParamPrinter.VisitParmVarDecl(D->getParamDecl(i)); 435193326Sed } 436198092Srdivacky 437193326Sed if (FT->isVariadic()) { 438193326Sed if (D->getNumParams()) POut << ", "; 439193326Sed POut << "..."; 440193326Sed } 441223017Sdim } else if (D->doesThisDeclarationHaveABody() && !D->hasPrototype()) { 442193326Sed for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) { 443193326Sed if (i) 444193326Sed Proto += ", "; 445193326Sed Proto += D->getParamDecl(i)->getNameAsString(); 446193326Sed } 447193326Sed } 448193326Sed 449193326Sed Proto += ")"; 450200583Srdivacky 451239462Sdim if (FT) { 452239462Sdim if (FT->isConst()) 453218893Sdim Proto += " const"; 454239462Sdim if (FT->isVolatile()) 455218893Sdim Proto += " volatile"; 456239462Sdim if (FT->isRestrict()) 457218893Sdim Proto += " restrict"; 458218893Sdim } 459221345Sdim 460221345Sdim if (FT && FT->hasDynamicExceptionSpec()) { 461200583Srdivacky Proto += " throw("; 462221345Sdim if (FT->getExceptionSpecType() == EST_MSAny) 463200583Srdivacky Proto += "..."; 464200583Srdivacky else 465200583Srdivacky for (unsigned I = 0, N = FT->getNumExceptions(); I != N; ++I) { 466200583Srdivacky if (I) 467200583Srdivacky Proto += ", "; 468221345Sdim 469243830Sdim Proto += FT->getExceptionType(I).getAsString(SubPolicy); 470200583Srdivacky } 471200583Srdivacky Proto += ")"; 472221345Sdim } else if (FT && isNoexceptExceptionSpec(FT->getExceptionSpecType())) { 473221345Sdim Proto += " noexcept"; 474221345Sdim if (FT->getExceptionSpecType() == EST_ComputedNoexcept) { 475221345Sdim Proto += "("; 476221345Sdim llvm::raw_string_ostream EOut(Proto); 477239462Sdim FT->getNoexceptExpr()->printPretty(EOut, 0, SubPolicy, 478221345Sdim Indentation); 479221345Sdim EOut.flush(); 480221345Sdim Proto += EOut.str(); 481221345Sdim Proto += ")"; 482221345Sdim } 483200583Srdivacky } 484200583Srdivacky 485249423Sdim if (CDecl) { 486223017Sdim bool HasInitializerList = false; 487223017Sdim for (CXXConstructorDecl::init_const_iterator B = CDecl->init_begin(), 488223017Sdim E = CDecl->init_end(); 489223017Sdim B != E; ++B) { 490223017Sdim CXXCtorInitializer * BMInitializer = (*B); 491223017Sdim if (BMInitializer->isInClassMemberInitializer()) 492223017Sdim continue; 493223017Sdim 494223017Sdim if (!HasInitializerList) { 495223017Sdim Proto += " : "; 496223017Sdim Out << Proto; 497223017Sdim Proto.clear(); 498223017Sdim HasInitializerList = true; 499223017Sdim } else 500223017Sdim Out << ", "; 501223017Sdim 502223017Sdim if (BMInitializer->isAnyMemberInitializer()) { 503223017Sdim FieldDecl *FD = BMInitializer->getAnyMember(); 504226633Sdim Out << *FD; 505223017Sdim } else { 506226633Sdim Out << QualType(BMInitializer->getBaseClass(), 0).getAsString(Policy); 507223017Sdim } 508223017Sdim 509223017Sdim Out << "("; 510223017Sdim if (!BMInitializer->getInit()) { 511223017Sdim // Nothing to print 512223017Sdim } else { 513223017Sdim Expr *Init = BMInitializer->getInit(); 514223017Sdim if (ExprWithCleanups *Tmp = dyn_cast<ExprWithCleanups>(Init)) 515223017Sdim Init = Tmp->getSubExpr(); 516203955Srdivacky 517223017Sdim Init = Init->IgnoreParens(); 518223017Sdim 519223017Sdim Expr *SimpleInit = 0; 520223017Sdim Expr **Args = 0; 521223017Sdim unsigned NumArgs = 0; 522223017Sdim if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) { 523223017Sdim Args = ParenList->getExprs(); 524223017Sdim NumArgs = ParenList->getNumExprs(); 525223017Sdim } else if (CXXConstructExpr *Construct 526223017Sdim = dyn_cast<CXXConstructExpr>(Init)) { 527223017Sdim Args = Construct->getArgs(); 528223017Sdim NumArgs = Construct->getNumArgs(); 529223017Sdim } else 530223017Sdim SimpleInit = Init; 531223017Sdim 532223017Sdim if (SimpleInit) 533239462Sdim SimpleInit->printPretty(Out, 0, Policy, Indentation); 534223017Sdim else { 535223017Sdim for (unsigned I = 0; I != NumArgs; ++I) { 536223017Sdim if (isa<CXXDefaultArgExpr>(Args[I])) 537223017Sdim break; 538223017Sdim 539223017Sdim if (I) 540223017Sdim Out << ", "; 541239462Sdim Args[I]->printPretty(Out, 0, Policy, Indentation); 542203955Srdivacky } 543198092Srdivacky } 544198092Srdivacky } 545223017Sdim Out << ")"; 546198092Srdivacky } 547249423Sdim if (!Proto.empty()) 548249423Sdim Out << Proto; 549249423Sdim } else { 550249423Sdim if (FT && FT->hasTrailingReturn()) { 551249423Sdim Out << "auto " << Proto << " -> "; 552249423Sdim Proto.clear(); 553249423Sdim } 554249423Sdim AFT->getResultType().print(Out, Policy, Proto); 555198092Srdivacky } 556193326Sed } else { 557239462Sdim Ty.print(Out, Policy, Proto); 558193326Sed } 559193326Sed 560234353Sdim prettyPrintAttributes(D); 561193326Sed 562193326Sed if (D->isPure()) 563193326Sed Out << " = 0"; 564223017Sdim else if (D->isDeletedAsWritten()) 565193326Sed Out << " = delete"; 566249423Sdim else if (D->isExplicitlyDefaulted()) 567249423Sdim Out << " = default"; 568243830Sdim else if (D->doesThisDeclarationHaveABody() && !Policy.TerseOutput) { 569193326Sed if (!D->hasPrototype() && D->getNumParams()) { 570193326Sed // This is a K&R function definition, so we need to print the 571193326Sed // parameters. 572193326Sed Out << '\n'; 573239462Sdim DeclPrinter ParamPrinter(Out, SubPolicy, Indentation); 574193326Sed Indentation += Policy.Indentation; 575193326Sed for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) { 576193326Sed Indent(); 577193326Sed ParamPrinter.VisitParmVarDecl(D->getParamDecl(i)); 578193326Sed Out << ";\n"; 579193326Sed } 580193326Sed Indentation -= Policy.Indentation; 581193326Sed } else 582193326Sed Out << ' '; 583193326Sed 584239462Sdim D->getBody()->printPretty(Out, 0, SubPolicy, Indentation); 585193326Sed Out << '\n'; 586193326Sed } 587193326Sed} 588193326Sed 589249423Sdimvoid DeclPrinter::VisitFriendDecl(FriendDecl *D) { 590249423Sdim if (TypeSourceInfo *TSI = D->getFriendType()) { 591249423Sdim unsigned NumTPLists = D->getFriendTypeNumTemplateParameterLists(); 592249423Sdim for (unsigned i = 0; i < NumTPLists; ++i) 593249423Sdim PrintTemplateParameters(D->getFriendTypeTemplateParameterList(i)); 594249423Sdim Out << "friend "; 595249423Sdim Out << " " << TSI->getType().getAsString(Policy); 596249423Sdim } 597249423Sdim else if (FunctionDecl *FD = 598249423Sdim dyn_cast<FunctionDecl>(D->getFriendDecl())) { 599249423Sdim Out << "friend "; 600249423Sdim VisitFunctionDecl(FD); 601249423Sdim } 602249423Sdim else if (FunctionTemplateDecl *FTD = 603249423Sdim dyn_cast<FunctionTemplateDecl>(D->getFriendDecl())) { 604249423Sdim Out << "friend "; 605249423Sdim VisitFunctionTemplateDecl(FTD); 606249423Sdim } 607249423Sdim else if (ClassTemplateDecl *CTD = 608249423Sdim dyn_cast<ClassTemplateDecl>(D->getFriendDecl())) { 609249423Sdim Out << "friend "; 610249423Sdim VisitRedeclarableTemplateDecl(CTD); 611249423Sdim } 612249423Sdim} 613249423Sdim 614193326Sedvoid DeclPrinter::VisitFieldDecl(FieldDecl *D) { 615193326Sed if (!Policy.SuppressSpecifiers && D->isMutable()) 616193326Sed Out << "mutable "; 617226633Sdim if (!Policy.SuppressSpecifiers && D->isModulePrivate()) 618226633Sdim Out << "__module_private__ "; 619193326Sed 620239462Sdim Out << D->getType().stream(Policy, D->getName()); 621193326Sed 622193326Sed if (D->isBitField()) { 623193326Sed Out << " : "; 624239462Sdim D->getBitWidth()->printPretty(Out, 0, Policy, Indentation); 625193326Sed } 626223017Sdim 627223017Sdim Expr *Init = D->getInClassInitializer(); 628223017Sdim if (!Policy.SuppressInitializers && Init) { 629239462Sdim if (D->getInClassInitStyle() == ICIS_ListInit) 630239462Sdim Out << " "; 631239462Sdim else 632239462Sdim Out << " = "; 633239462Sdim Init->printPretty(Out, 0, Policy, Indentation); 634223017Sdim } 635234353Sdim prettyPrintAttributes(D); 636193326Sed} 637193326Sed 638218893Sdimvoid DeclPrinter::VisitLabelDecl(LabelDecl *D) { 639234353Sdim Out << *D << ":"; 640218893Sdim} 641218893Sdim 642218893Sdim 643193326Sedvoid DeclPrinter::VisitVarDecl(VarDecl *D) { 644249423Sdim StorageClass SC = D->getStorageClass(); 645249423Sdim if (!Policy.SuppressSpecifiers && SC != SC_None) 646249423Sdim Out << VarDecl::getStorageClassSpecifierString(SC) << " "; 647193326Sed 648193326Sed if (!Policy.SuppressSpecifiers && D->isThreadSpecified()) 649193326Sed Out << "__thread "; 650226633Sdim if (!Policy.SuppressSpecifiers && D->isModulePrivate()) 651226633Sdim Out << "__module_private__ "; 652193326Sed 653193326Sed QualType T = D->getType(); 654198893Srdivacky if (ParmVarDecl *Parm = dyn_cast<ParmVarDecl>(D)) 655193326Sed T = Parm->getOriginalType(); 656239462Sdim T.print(Out, Policy, D->getName()); 657221345Sdim Expr *Init = D->getInit(); 658221345Sdim if (!Policy.SuppressInitializers && Init) { 659234353Sdim bool ImplicitInit = false; 660249423Sdim if (CXXConstructExpr *Construct = 661249423Sdim dyn_cast<CXXConstructExpr>(Init->IgnoreImplicit())) { 662249423Sdim if (D->getInitStyle() == VarDecl::CallInit && 663249423Sdim !Construct->isListInitialization()) { 664249423Sdim ImplicitInit = Construct->getNumArgs() == 0 || 665249423Sdim Construct->getArg(0)->isDefaultArgument(); 666249423Sdim } 667249423Sdim } 668234353Sdim if (!ImplicitInit) { 669243830Sdim if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init)) 670234353Sdim Out << "("; 671234353Sdim else if (D->getInitStyle() == VarDecl::CInit) { 672234353Sdim Out << " = "; 673234353Sdim } 674239462Sdim Init->printPretty(Out, 0, Policy, Indentation); 675243830Sdim if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init)) 676234353Sdim Out << ")"; 677218893Sdim } 678193326Sed } 679234353Sdim prettyPrintAttributes(D); 680193326Sed} 681193326Sed 682193326Sedvoid DeclPrinter::VisitParmVarDecl(ParmVarDecl *D) { 683193326Sed VisitVarDecl(D); 684193326Sed} 685193326Sed 686193326Sedvoid DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) { 687193326Sed Out << "__asm ("; 688239462Sdim D->getAsmString()->printPretty(Out, 0, Policy, Indentation); 689193326Sed Out << ")"; 690193326Sed} 691193326Sed 692234353Sdimvoid DeclPrinter::VisitImportDecl(ImportDecl *D) { 693249423Sdim Out << "@import " << D->getImportedModule()->getFullModuleName() 694234353Sdim << ";\n"; 695234353Sdim} 696234353Sdim 697221345Sdimvoid DeclPrinter::VisitStaticAssertDecl(StaticAssertDecl *D) { 698221345Sdim Out << "static_assert("; 699239462Sdim D->getAssertExpr()->printPretty(Out, 0, Policy, Indentation); 700221345Sdim Out << ", "; 701239462Sdim D->getMessage()->printPretty(Out, 0, Policy, Indentation); 702221345Sdim Out << ")"; 703221345Sdim} 704221345Sdim 705193326Sed//---------------------------------------------------------------------------- 706193326Sed// C++ declarations 707193326Sed//---------------------------------------------------------------------------- 708193326Sedvoid DeclPrinter::VisitNamespaceDecl(NamespaceDecl *D) { 709239462Sdim if (D->isInline()) 710239462Sdim Out << "inline "; 711226633Sdim Out << "namespace " << *D << " {\n"; 712193326Sed VisitDeclContext(D); 713193326Sed Indent() << "}"; 714193326Sed} 715193326Sed 716193326Sedvoid DeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) { 717193326Sed Out << "using namespace "; 718193326Sed if (D->getQualifier()) 719193326Sed D->getQualifier()->print(Out, Policy); 720226633Sdim Out << *D->getNominatedNamespaceAsWritten(); 721193326Sed} 722193326Sed 723193326Sedvoid DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) { 724226633Sdim Out << "namespace " << *D << " = "; 725193326Sed if (D->getQualifier()) 726193326Sed D->getQualifier()->print(Out, Policy); 727226633Sdim Out << *D->getAliasedNamespace(); 728193326Sed} 729193326Sed 730249423Sdimvoid DeclPrinter::VisitEmptyDecl(EmptyDecl *D) { 731249423Sdim prettyPrintAttributes(D); 732249423Sdim} 733249423Sdim 734193326Sedvoid DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) { 735226633Sdim if (!Policy.SuppressSpecifiers && D->isModulePrivate()) 736226633Sdim Out << "__module_private__ "; 737193326Sed Out << D->getKindName(); 738207619Srdivacky if (D->getIdentifier()) 739226633Sdim Out << ' ' << *D; 740198092Srdivacky 741226633Sdim if (D->isCompleteDefinition()) { 742193326Sed // Print the base classes 743193326Sed if (D->getNumBases()) { 744193326Sed Out << " : "; 745198092Srdivacky for (CXXRecordDecl::base_class_iterator Base = D->bases_begin(), 746198092Srdivacky BaseEnd = D->bases_end(); Base != BaseEnd; ++Base) { 747193326Sed if (Base != D->bases_begin()) 748193326Sed Out << ", "; 749193326Sed 750193326Sed if (Base->isVirtual()) 751193326Sed Out << "virtual "; 752193326Sed 753198092Srdivacky AccessSpecifier AS = Base->getAccessSpecifierAsWritten(); 754198092Srdivacky if (AS != AS_none) 755198092Srdivacky Print(AS); 756198092Srdivacky Out << " " << Base->getType().getAsString(Policy); 757221345Sdim 758221345Sdim if (Base->isPackExpansion()) 759221345Sdim Out << "..."; 760193326Sed } 761193326Sed } 762193326Sed 763193326Sed // Print the class definition 764193326Sed // FIXME: Doesn't print access specifiers, e.g., "public:" 765193326Sed Out << " {\n"; 766193326Sed VisitDeclContext(D); 767193326Sed Indent() << "}"; 768198092Srdivacky } 769193326Sed} 770193326Sed 771193326Sedvoid DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) { 772193326Sed const char *l; 773193326Sed if (D->getLanguage() == LinkageSpecDecl::lang_c) 774193326Sed l = "C"; 775193326Sed else { 776193326Sed assert(D->getLanguage() == LinkageSpecDecl::lang_cxx && 777193326Sed "unknown language in linkage specification"); 778193326Sed l = "C++"; 779193326Sed } 780193326Sed 781193326Sed Out << "extern \"" << l << "\" "; 782193326Sed if (D->hasBraces()) { 783193326Sed Out << "{\n"; 784193326Sed VisitDeclContext(D); 785193326Sed Indent() << "}"; 786193326Sed } else 787195341Sed Visit(*D->decls_begin()); 788193326Sed} 789193326Sed 790249423Sdimvoid DeclPrinter::PrintTemplateParameters(const TemplateParameterList *Params, 791249423Sdim const TemplateArgumentList *Args) { 792226633Sdim assert(Params); 793226633Sdim assert(!Args || Params->size() == Args->size()); 794226633Sdim 795193576Sed Out << "template <"; 796198092Srdivacky 797193576Sed for (unsigned i = 0, e = Params->size(); i != e; ++i) { 798193576Sed if (i != 0) 799193576Sed Out << ", "; 800198092Srdivacky 801193576Sed const Decl *Param = Params->getParam(i); 802198092Srdivacky if (const TemplateTypeParmDecl *TTP = 803193576Sed dyn_cast<TemplateTypeParmDecl>(Param)) { 804198092Srdivacky 805193576Sed if (TTP->wasDeclaredWithTypename()) 806193576Sed Out << "typename "; 807193576Sed else 808193576Sed Out << "class "; 809193576Sed 810194179Sed if (TTP->isParameterPack()) 811194179Sed Out << "... "; 812198092Srdivacky 813234353Sdim Out << *TTP; 814193576Sed 815226633Sdim if (Args) { 816193576Sed Out << " = "; 817226633Sdim Args->get(i).print(Policy, Out); 818226633Sdim } else if (TTP->hasDefaultArgument()) { 819226633Sdim Out << " = "; 820193576Sed Out << TTP->getDefaultArgument().getAsString(Policy); 821193576Sed }; 822198092Srdivacky } else if (const NonTypeTemplateParmDecl *NTTP = 823193576Sed dyn_cast<NonTypeTemplateParmDecl>(Param)) { 824193576Sed Out << NTTP->getType().getAsString(Policy); 825193576Sed 826218893Sdim if (NTTP->isParameterPack() && !isa<PackExpansionType>(NTTP->getType())) 827218893Sdim Out << "..."; 828218893Sdim 829193576Sed if (IdentifierInfo *Name = NTTP->getIdentifier()) { 830193576Sed Out << ' '; 831193576Sed Out << Name->getName(); 832193576Sed } 833198092Srdivacky 834226633Sdim if (Args) { 835193576Sed Out << " = "; 836226633Sdim Args->get(i).print(Policy, Out); 837226633Sdim } else if (NTTP->hasDefaultArgument()) { 838226633Sdim Out << " = "; 839239462Sdim NTTP->getDefaultArgument()->printPretty(Out, 0, Policy, Indentation); 840193576Sed } 841221345Sdim } else if (const TemplateTemplateParmDecl *TTPD = 842221345Sdim dyn_cast<TemplateTemplateParmDecl>(Param)) { 843221345Sdim VisitTemplateDecl(TTPD); 844221345Sdim // FIXME: print the default argument, if present. 845193576Sed } 846193576Sed } 847198092Srdivacky 848193576Sed Out << "> "; 849226633Sdim} 850193576Sed 851226633Sdimvoid DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) { 852226633Sdim PrintTemplateParameters(D->getTemplateParameters()); 853226633Sdim 854221345Sdim if (const TemplateTemplateParmDecl *TTP = 855221345Sdim dyn_cast<TemplateTemplateParmDecl>(D)) { 856218893Sdim Out << "class "; 857218893Sdim if (TTP->isParameterPack()) 858218893Sdim Out << "..."; 859218893Sdim Out << D->getName(); 860210299Sed } else { 861210299Sed Visit(D->getTemplatedDecl()); 862210299Sed } 863193326Sed} 864193326Sed 865226633Sdimvoid DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { 866226633Sdim if (PrintInstantiation) { 867226633Sdim TemplateParameterList *Params = D->getTemplateParameters(); 868226633Sdim for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(), E = D->spec_end(); 869226633Sdim I != E; ++I) { 870226633Sdim PrintTemplateParameters(Params, (*I)->getTemplateSpecializationArgs()); 871226633Sdim Visit(*I); 872226633Sdim } 873226633Sdim } 874226633Sdim 875226633Sdim return VisitRedeclarableTemplateDecl(D); 876226633Sdim} 877226633Sdim 878226633Sdimvoid DeclPrinter::VisitClassTemplateDecl(ClassTemplateDecl *D) { 879226633Sdim if (PrintInstantiation) { 880226633Sdim TemplateParameterList *Params = D->getTemplateParameters(); 881226633Sdim for (ClassTemplateDecl::spec_iterator I = D->spec_begin(), E = D->spec_end(); 882226633Sdim I != E; ++I) { 883226633Sdim PrintTemplateParameters(Params, &(*I)->getTemplateArgs()); 884226633Sdim Visit(*I); 885226633Sdim Out << '\n'; 886226633Sdim } 887226633Sdim } 888226633Sdim 889226633Sdim return VisitRedeclarableTemplateDecl(D); 890226633Sdim} 891226633Sdim 892193326Sed//---------------------------------------------------------------------------- 893193326Sed// Objective-C declarations 894193326Sed//---------------------------------------------------------------------------- 895193326Sed 896193326Sedvoid DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) { 897193326Sed if (OMD->isInstanceMethod()) 898193326Sed Out << "- "; 899198092Srdivacky else 900193326Sed Out << "+ "; 901193326Sed if (!OMD->getResultType().isNull()) 902193326Sed Out << '(' << OMD->getResultType().getAsString(Policy) << ")"; 903198092Srdivacky 904193326Sed std::string name = OMD->getSelector().getAsString(); 905193326Sed std::string::size_type pos, lastPos = 0; 906193326Sed for (ObjCMethodDecl::param_iterator PI = OMD->param_begin(), 907193326Sed E = OMD->param_end(); PI != E; ++PI) { 908198092Srdivacky // FIXME: selector is missing here! 909226633Sdim pos = name.find_first_of(':', lastPos); 910193326Sed Out << " " << name.substr(lastPos, pos - lastPos); 911226633Sdim Out << ":(" << (*PI)->getType().getAsString(Policy) << ')' << **PI; 912193326Sed lastPos = pos + 1; 913193326Sed } 914198092Srdivacky 915193326Sed if (OMD->param_begin() == OMD->param_end()) 916193326Sed Out << " " << name; 917198092Srdivacky 918193326Sed if (OMD->isVariadic()) 919193326Sed Out << ", ..."; 920198092Srdivacky 921243830Sdim if (OMD->getBody() && !Policy.TerseOutput) { 922193326Sed Out << ' '; 923239462Sdim OMD->getBody()->printPretty(Out, 0, Policy); 924193326Sed Out << '\n'; 925193326Sed } 926249423Sdim else if (Policy.PolishForDeclaration) 927249423Sdim Out << ';'; 928193326Sed} 929193326Sed 930193326Sedvoid DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) { 931193326Sed std::string I = OID->getNameAsString(); 932193326Sed ObjCInterfaceDecl *SID = OID->getSuperClass(); 933193326Sed 934193326Sed if (SID) 935226633Sdim Out << "@implementation " << I << " : " << *SID; 936193326Sed else 937193326Sed Out << "@implementation " << I; 938249423Sdim 939249423Sdim if (OID->ivar_size() > 0) { 940249423Sdim Out << "{\n"; 941249423Sdim Indentation += Policy.Indentation; 942249423Sdim for (ObjCImplementationDecl::ivar_iterator I = OID->ivar_begin(), 943249423Sdim E = OID->ivar_end(); I != E; ++I) { 944249423Sdim Indent() << I->getType().getAsString(Policy) << ' ' << **I << ";\n"; 945249423Sdim } 946249423Sdim Indentation -= Policy.Indentation; 947249423Sdim Out << "}\n"; 948249423Sdim } 949193326Sed VisitDeclContext(OID, false); 950193326Sed Out << "@end"; 951193326Sed} 952193326Sed 953193326Sedvoid DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) { 954193326Sed std::string I = OID->getNameAsString(); 955193326Sed ObjCInterfaceDecl *SID = OID->getSuperClass(); 956193326Sed 957234353Sdim if (!OID->isThisDeclarationADefinition()) { 958234353Sdim Out << "@class " << I << ";"; 959234353Sdim return; 960234353Sdim } 961249423Sdim bool eolnOut = false; 962193326Sed if (SID) 963226633Sdim Out << "@interface " << I << " : " << *SID; 964193326Sed else 965193326Sed Out << "@interface " << I; 966198092Srdivacky 967193326Sed // Protocols? 968193326Sed const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols(); 969193326Sed if (!Protocols.empty()) { 970193326Sed for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 971193326Sed E = Protocols.end(); I != E; ++I) 972226633Sdim Out << (I == Protocols.begin() ? '<' : ',') << **I; 973249423Sdim Out << "> "; 974193326Sed } 975198092Srdivacky 976193326Sed if (OID->ivar_size() > 0) { 977193326Sed Out << "{\n"; 978249423Sdim eolnOut = true; 979193326Sed Indentation += Policy.Indentation; 980193326Sed for (ObjCInterfaceDecl::ivar_iterator I = OID->ivar_begin(), 981193326Sed E = OID->ivar_end(); I != E; ++I) { 982239462Sdim Indent() << I->getType().getAsString(Policy) << ' ' << **I << ";\n"; 983193326Sed } 984193326Sed Indentation -= Policy.Indentation; 985193326Sed Out << "}\n"; 986193326Sed } 987249423Sdim else if (SID) { 988249423Sdim Out << "\n"; 989249423Sdim eolnOut = true; 990249423Sdim } 991198092Srdivacky 992193326Sed VisitDeclContext(OID, false); 993249423Sdim if (!eolnOut) 994249423Sdim Out << ' '; 995193326Sed Out << "@end"; 996193326Sed // FIXME: implement the rest... 997193326Sed} 998193326Sed 999234353Sdimvoid DeclPrinter::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) { 1000234353Sdim if (!PID->isThisDeclarationADefinition()) { 1001249423Sdim Out << "@protocol " << *PID << ";\n"; 1002234353Sdim return; 1003193326Sed } 1004249423Sdim // Protocols? 1005249423Sdim const ObjCList<ObjCProtocolDecl> &Protocols = PID->getReferencedProtocols(); 1006249423Sdim if (!Protocols.empty()) { 1007249423Sdim Out << "@protocol " << *PID; 1008249423Sdim for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(), 1009249423Sdim E = Protocols.end(); I != E; ++I) 1010249423Sdim Out << (I == Protocols.begin() ? '<' : ',') << **I; 1011249423Sdim Out << ">\n"; 1012249423Sdim } else 1013249423Sdim Out << "@protocol " << *PID << '\n'; 1014193326Sed VisitDeclContext(PID, false); 1015193326Sed Out << "@end"; 1016193326Sed} 1017193326Sed 1018193326Sedvoid DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) { 1019226633Sdim Out << "@implementation " << *PID->getClassInterface() << '(' << *PID <<")\n"; 1020193326Sed 1021193326Sed VisitDeclContext(PID, false); 1022193326Sed Out << "@end"; 1023193326Sed // FIXME: implement the rest... 1024193326Sed} 1025193326Sed 1026193326Sedvoid DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) { 1027226633Sdim Out << "@interface " << *PID->getClassInterface() << '(' << *PID << ")\n"; 1028249423Sdim if (PID->ivar_size() > 0) { 1029249423Sdim Out << "{\n"; 1030249423Sdim Indentation += Policy.Indentation; 1031249423Sdim for (ObjCCategoryDecl::ivar_iterator I = PID->ivar_begin(), 1032249423Sdim E = PID->ivar_end(); I != E; ++I) { 1033249423Sdim Indent() << I->getType().getAsString(Policy) << ' ' << **I << ";\n"; 1034249423Sdim } 1035249423Sdim Indentation -= Policy.Indentation; 1036249423Sdim Out << "}\n"; 1037249423Sdim } 1038249423Sdim 1039193326Sed VisitDeclContext(PID, false); 1040193326Sed Out << "@end"; 1041198092Srdivacky 1042193326Sed // FIXME: implement the rest... 1043193326Sed} 1044193326Sed 1045193326Sedvoid DeclPrinter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID) { 1046226633Sdim Out << "@compatibility_alias " << *AID 1047226633Sdim << ' ' << *AID->getClassInterface() << ";\n"; 1048193326Sed} 1049193326Sed 1050193326Sed/// PrintObjCPropertyDecl - print a property declaration. 1051193326Sed/// 1052193326Sedvoid DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) { 1053193326Sed if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Required) 1054193326Sed Out << "@required\n"; 1055193326Sed else if (PDecl->getPropertyImplementation() == ObjCPropertyDecl::Optional) 1056193326Sed Out << "@optional\n"; 1057198092Srdivacky 1058193326Sed Out << "@property"; 1059193326Sed if (PDecl->getPropertyAttributes() != ObjCPropertyDecl::OBJC_PR_noattr) { 1060193326Sed bool first = true; 1061193326Sed Out << " ("; 1062198092Srdivacky if (PDecl->getPropertyAttributes() & 1063193326Sed ObjCPropertyDecl::OBJC_PR_readonly) { 1064193326Sed Out << (first ? ' ' : ',') << "readonly"; 1065193326Sed first = false; 1066226633Sdim } 1067198092Srdivacky 1068226633Sdim if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_getter) { 1069226633Sdim Out << (first ? ' ' : ',') << "getter = " 1070226633Sdim << PDecl->getGetterName().getAsString(); 1071226633Sdim first = false; 1072226633Sdim } 1073226633Sdim if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_setter) { 1074226633Sdim Out << (first ? ' ' : ',') << "setter = " 1075226633Sdim << PDecl->getSetterName().getAsString(); 1076226633Sdim first = false; 1077226633Sdim } 1078198092Srdivacky 1079226633Sdim if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_assign) { 1080226633Sdim Out << (first ? ' ' : ',') << "assign"; 1081226633Sdim first = false; 1082226633Sdim } 1083198092Srdivacky 1084226633Sdim if (PDecl->getPropertyAttributes() & 1085226633Sdim ObjCPropertyDecl::OBJC_PR_readwrite) { 1086226633Sdim Out << (first ? ' ' : ',') << "readwrite"; 1087226633Sdim first = false; 1088226633Sdim } 1089198092Srdivacky 1090226633Sdim if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_retain) { 1091226633Sdim Out << (first ? ' ' : ',') << "retain"; 1092226633Sdim first = false; 1093226633Sdim } 1094198092Srdivacky 1095226633Sdim if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_strong) { 1096226633Sdim Out << (first ? ' ' : ',') << "strong"; 1097226633Sdim first = false; 1098226633Sdim } 1099224145Sdim 1100226633Sdim if (PDecl->getPropertyAttributes() & ObjCPropertyDecl::OBJC_PR_copy) { 1101226633Sdim Out << (first ? ' ' : ',') << "copy"; 1102226633Sdim first = false; 1103226633Sdim } 1104198092Srdivacky 1105226633Sdim if (PDecl->getPropertyAttributes() & 1106226633Sdim ObjCPropertyDecl::OBJC_PR_nonatomic) { 1107226633Sdim Out << (first ? ' ' : ',') << "nonatomic"; 1108226633Sdim first = false; 1109226633Sdim } 1110226633Sdim if (PDecl->getPropertyAttributes() & 1111226633Sdim ObjCPropertyDecl::OBJC_PR_atomic) { 1112226633Sdim Out << (first ? ' ' : ',') << "atomic"; 1113226633Sdim first = false; 1114226633Sdim } 1115226633Sdim 1116226633Sdim (void) first; // Silence dead store warning due to idiomatic code. 1117226633Sdim Out << " )"; 1118193326Sed } 1119226633Sdim Out << ' ' << PDecl->getType().getAsString(Policy) << ' ' << *PDecl; 1120249423Sdim if (Policy.PolishForDeclaration) 1121249423Sdim Out << ';'; 1122193326Sed} 1123193326Sed 1124193326Sedvoid DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) { 1125193326Sed if (PID->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize) 1126193326Sed Out << "@synthesize "; 1127193326Sed else 1128193326Sed Out << "@dynamic "; 1129226633Sdim Out << *PID->getPropertyDecl(); 1130193326Sed if (PID->getPropertyIvarDecl()) 1131226633Sdim Out << '=' << *PID->getPropertyIvarDecl(); 1132193326Sed} 1133198092Srdivacky 1134198092Srdivackyvoid DeclPrinter::VisitUsingDecl(UsingDecl *D) { 1135198092Srdivacky Out << "using "; 1136219077Sdim D->getQualifier()->print(Out, Policy); 1137226633Sdim Out << *D; 1138198092Srdivacky} 1139198092Srdivacky 1140199482Srdivackyvoid 1141199482SrdivackyDeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) { 1142199482Srdivacky Out << "using typename "; 1143219077Sdim D->getQualifier()->print(Out, Policy); 1144207619Srdivacky Out << D->getDeclName(); 1145199482Srdivacky} 1146199482Srdivacky 1147199482Srdivackyvoid DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) { 1148198092Srdivacky Out << "using "; 1149219077Sdim D->getQualifier()->print(Out, Policy); 1150249423Sdim Out << D->getName(); 1151198092Srdivacky} 1152199482Srdivacky 1153199482Srdivackyvoid DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) { 1154199482Srdivacky // ignore 1155199482Srdivacky} 1156249423Sdim 1157249423Sdimvoid DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) { 1158249423Sdim Out << "#pragma omp threadprivate"; 1159249423Sdim if (!D->varlist_empty()) { 1160249423Sdim for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(), 1161249423Sdim E = D->varlist_end(); 1162249423Sdim I != E; ++I) { 1163249423Sdim Out << (I == D->varlist_begin() ? '(' : ',') 1164249423Sdim << *cast<NamedDecl>((*I)->getDecl()); 1165249423Sdim } 1166249423Sdim Out << ")"; 1167249423Sdim } 1168249423Sdim} 1169249423Sdim 1170