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