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