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