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