1 //===--- DeclPrinter.cpp - Printing implementation for Decl ASTs ----------===//
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
7 //===----------------------------------------------------------------------===//
9 // This file implements the Decl::print method, which pretty prints the
10 // AST back out to C/Objective-C/C++/Objective-C++ code.
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
;
28 class DeclPrinter
: public DeclVisitor
<DeclPrinter
> {
30 PrintingPolicy Policy
;
31 const ASTContext
&Context
;
33 bool PrintInstantiation
;
35 raw_ostream
& Indent() { return Indent(Indentation
); }
36 raw_ostream
& Indent(unsigned Indentation
);
37 void ProcessDeclGroup(SmallVectorImpl
<Decl
*>& Decls
);
39 void Print(AccessSpecifier AS
);
40 void PrintConstructorInitializers(CXXConstructorDecl
*CDecl
,
43 /// Print an Objective-C method type in parentheses.
45 /// \param Quals The Objective-C declaration qualifiers.
46 /// \param T The type to print.
47 void PrintObjCMethodType(ASTContext
&Ctx
, Decl::ObjCDeclQualifier Quals
,
50 void PrintObjCTypeParams(ObjCTypeParamList
*Params
);
52 enum class AttrPrintLoc
{
58 LLVM_MARK_AS_BITMASK_ENUM(/*DefaultValue=*/Any
)
61 void prettyPrintAttributes(Decl
*D
, raw_ostream
&out
,
62 AttrPrintLoc loc
= AttrPrintLoc::Any
);
65 DeclPrinter(raw_ostream
&Out
, const PrintingPolicy
&Policy
,
66 const ASTContext
&Context
, unsigned Indentation
= 0,
67 bool PrintInstantiation
= false)
68 : Out(Out
), Policy(Policy
), Context(Context
), Indentation(Indentation
),
69 PrintInstantiation(PrintInstantiation
) {}
71 void VisitDeclContext(DeclContext
*DC
, bool Indent
= true);
73 void VisitTranslationUnitDecl(TranslationUnitDecl
*D
);
74 void VisitTypedefDecl(TypedefDecl
*D
);
75 void VisitTypeAliasDecl(TypeAliasDecl
*D
);
76 void VisitEnumDecl(EnumDecl
*D
);
77 void VisitRecordDecl(RecordDecl
*D
);
78 void VisitEnumConstantDecl(EnumConstantDecl
*D
);
79 void VisitEmptyDecl(EmptyDecl
*D
);
80 void VisitFunctionDecl(FunctionDecl
*D
);
81 void VisitFriendDecl(FriendDecl
*D
);
82 void VisitFieldDecl(FieldDecl
*D
);
83 void VisitVarDecl(VarDecl
*D
);
84 void VisitLabelDecl(LabelDecl
*D
);
85 void VisitParmVarDecl(ParmVarDecl
*D
);
86 void VisitFileScopeAsmDecl(FileScopeAsmDecl
*D
);
87 void VisitTopLevelStmtDecl(TopLevelStmtDecl
*D
);
88 void VisitImportDecl(ImportDecl
*D
);
89 void VisitStaticAssertDecl(StaticAssertDecl
*D
);
90 void VisitNamespaceDecl(NamespaceDecl
*D
);
91 void VisitUsingDirectiveDecl(UsingDirectiveDecl
*D
);
92 void VisitNamespaceAliasDecl(NamespaceAliasDecl
*D
);
93 void VisitCXXRecordDecl(CXXRecordDecl
*D
);
94 void VisitLinkageSpecDecl(LinkageSpecDecl
*D
);
95 void VisitTemplateDecl(const TemplateDecl
*D
);
96 void VisitFunctionTemplateDecl(FunctionTemplateDecl
*D
);
97 void VisitClassTemplateDecl(ClassTemplateDecl
*D
);
98 void VisitClassTemplateSpecializationDecl(
99 ClassTemplateSpecializationDecl
*D
);
100 void VisitClassTemplatePartialSpecializationDecl(
101 ClassTemplatePartialSpecializationDecl
*D
);
102 void VisitObjCMethodDecl(ObjCMethodDecl
*D
);
103 void VisitObjCImplementationDecl(ObjCImplementationDecl
*D
);
104 void VisitObjCInterfaceDecl(ObjCInterfaceDecl
*D
);
105 void VisitObjCProtocolDecl(ObjCProtocolDecl
*D
);
106 void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl
*D
);
107 void VisitObjCCategoryDecl(ObjCCategoryDecl
*D
);
108 void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl
*D
);
109 void VisitObjCPropertyDecl(ObjCPropertyDecl
*D
);
110 void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl
*D
);
111 void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl
*D
);
112 void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl
*D
);
113 void VisitUsingDecl(UsingDecl
*D
);
114 void VisitUsingEnumDecl(UsingEnumDecl
*D
);
115 void VisitUsingShadowDecl(UsingShadowDecl
*D
);
116 void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl
*D
);
117 void VisitOMPAllocateDecl(OMPAllocateDecl
*D
);
118 void VisitOMPRequiresDecl(OMPRequiresDecl
*D
);
119 void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl
*D
);
120 void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl
*D
);
121 void VisitOMPCapturedExprDecl(OMPCapturedExprDecl
*D
);
122 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl
*TTP
);
123 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl
*NTTP
);
124 void VisitHLSLBufferDecl(HLSLBufferDecl
*D
);
126 void printTemplateParameters(const TemplateParameterList
*Params
,
127 bool OmitTemplateKW
= false);
128 void printTemplateArguments(llvm::ArrayRef
<TemplateArgument
> Args
,
129 const TemplateParameterList
*Params
);
130 void printTemplateArguments(llvm::ArrayRef
<TemplateArgumentLoc
> Args
,
131 const TemplateParameterList
*Params
);
133 inline void prettyPrintAttributes(Decl
*D
) {
134 prettyPrintAttributes(D
, Out
);
137 void prettyPrintPragmas(Decl
*D
);
138 void printDeclType(QualType T
, StringRef DeclName
, bool Pack
= false);
142 void Decl::print(raw_ostream
&Out
, unsigned Indentation
,
143 bool PrintInstantiation
) const {
144 print(Out
, getASTContext().getPrintingPolicy(), Indentation
, PrintInstantiation
);
147 void Decl::print(raw_ostream
&Out
, const PrintingPolicy
&Policy
,
148 unsigned Indentation
, bool PrintInstantiation
) const {
149 DeclPrinter
Printer(Out
, Policy
, getASTContext(), Indentation
,
151 Printer
.Visit(const_cast<Decl
*>(this));
154 void TemplateParameterList::print(raw_ostream
&Out
, const ASTContext
&Context
,
155 bool OmitTemplateKW
) const {
156 print(Out
, Context
, Context
.getPrintingPolicy(), OmitTemplateKW
);
159 void TemplateParameterList::print(raw_ostream
&Out
, const ASTContext
&Context
,
160 const PrintingPolicy
&Policy
,
161 bool OmitTemplateKW
) const {
162 DeclPrinter
Printer(Out
, Policy
, Context
);
163 Printer
.printTemplateParameters(this, OmitTemplateKW
);
166 static QualType
GetBaseType(QualType T
) {
167 // FIXME: This should be on the Type class!
168 QualType BaseType
= T
;
169 while (!BaseType
->isSpecifierType()) {
170 if (const PointerType
*PTy
= BaseType
->getAs
<PointerType
>())
171 BaseType
= PTy
->getPointeeType();
172 else if (const ObjCObjectPointerType
*OPT
=
173 BaseType
->getAs
<ObjCObjectPointerType
>())
174 BaseType
= OPT
->getPointeeType();
175 else if (const BlockPointerType
*BPy
= BaseType
->getAs
<BlockPointerType
>())
176 BaseType
= BPy
->getPointeeType();
177 else if (const ArrayType
*ATy
= dyn_cast
<ArrayType
>(BaseType
))
178 BaseType
= ATy
->getElementType();
179 else if (const FunctionType
*FTy
= BaseType
->getAs
<FunctionType
>())
180 BaseType
= FTy
->getReturnType();
181 else if (const VectorType
*VTy
= BaseType
->getAs
<VectorType
>())
182 BaseType
= VTy
->getElementType();
183 else if (const ReferenceType
*RTy
= BaseType
->getAs
<ReferenceType
>())
184 BaseType
= RTy
->getPointeeType();
185 else if (const AutoType
*ATy
= BaseType
->getAs
<AutoType
>())
186 BaseType
= ATy
->getDeducedType();
187 else if (const ParenType
*PTy
= BaseType
->getAs
<ParenType
>())
188 BaseType
= PTy
->desugar();
190 // This must be a syntax error.
196 static QualType
getDeclType(Decl
* D
) {
197 if (TypedefNameDecl
* TDD
= dyn_cast
<TypedefNameDecl
>(D
))
198 return TDD
->getUnderlyingType();
199 if (ValueDecl
* VD
= dyn_cast
<ValueDecl
>(D
))
200 return VD
->getType();
204 void Decl::printGroup(Decl
** Begin
, unsigned NumDecls
,
205 raw_ostream
&Out
, const PrintingPolicy
&Policy
,
206 unsigned Indentation
) {
208 (*Begin
)->print(Out
, Policy
, Indentation
);
212 Decl
** End
= Begin
+ NumDecls
;
213 TagDecl
* TD
= dyn_cast
<TagDecl
>(*Begin
);
217 PrintingPolicy
SubPolicy(Policy
);
220 for ( ; Begin
!= End
; ++Begin
) {
223 SubPolicy
.IncludeTagDefinition
= true;
224 SubPolicy
.SuppressSpecifiers
= false;
227 if (!isFirst
) Out
<< ", ";
228 SubPolicy
.IncludeTagDefinition
= false;
229 SubPolicy
.SuppressSpecifiers
= true;
232 (*Begin
)->print(Out
, SubPolicy
, Indentation
);
236 LLVM_DUMP_METHOD
void DeclContext::dumpDeclContext() const {
237 // Get the translation unit
238 const DeclContext
*DC
= this;
239 while (!DC
->isTranslationUnit())
240 DC
= DC
->getParent();
242 ASTContext
&Ctx
= cast
<TranslationUnitDecl
>(DC
)->getASTContext();
243 DeclPrinter
Printer(llvm::errs(), Ctx
.getPrintingPolicy(), Ctx
, 0);
244 Printer
.VisitDeclContext(const_cast<DeclContext
*>(this), /*Indent=*/false);
247 raw_ostream
& DeclPrinter::Indent(unsigned Indentation
) {
248 for (unsigned i
= 0; i
!= Indentation
; ++i
)
253 // For CLANG_ATTR_LIST_CanPrintOnLeft macro.
254 #include "clang/Basic/AttrLeftSideCanPrintList.inc"
256 // For CLANG_ATTR_LIST_PrintOnLeft macro.
257 #include "clang/Basic/AttrLeftSideMustPrintList.inc"
259 static bool canPrintOnLeftSide(attr::Kind kind
) {
260 #ifdef CLANG_ATTR_LIST_CanPrintOnLeft
262 CLANG_ATTR_LIST_CanPrintOnLeft
272 static bool canPrintOnLeftSide(const Attr
*A
) {
273 if (A
->isStandardAttributeSyntax())
276 return canPrintOnLeftSide(A
->getKind());
279 static bool mustPrintOnLeftSide(attr::Kind kind
) {
280 #ifdef CLANG_ATTR_LIST_PrintOnLeft
282 CLANG_ATTR_LIST_PrintOnLeft
292 static bool mustPrintOnLeftSide(const Attr
*A
) {
293 if (A
->isDeclspecAttribute())
296 return mustPrintOnLeftSide(A
->getKind());
299 void DeclPrinter::prettyPrintAttributes(Decl
*D
, llvm::raw_ostream
&Out
,
301 if (Policy
.PolishForDeclaration
)
305 AttrVec
&Attrs
= D
->getAttrs();
306 for (auto *A
: Attrs
) {
307 if (A
->isInherited() || A
->isImplicit())
310 AttrPrintLoc AttrLoc
= AttrPrintLoc::Right
;
311 if (mustPrintOnLeftSide(A
)) {
312 // If we must always print on left side (e.g. declspec), then mark as
314 AttrLoc
= AttrPrintLoc::Left
;
315 } else if (canPrintOnLeftSide(A
)) {
316 // For functions with body defined we print the attributes on the left
317 // side so that GCC accept our dumps as well.
318 if (const FunctionDecl
*FD
= dyn_cast
<FunctionDecl
>(D
);
319 FD
&& FD
->isThisDeclarationADefinition())
320 // In case Decl is a function with a body, then attrs should be print
322 AttrLoc
= AttrPrintLoc::Left
;
324 // In case it is a variable declaration with a ctor, then allow
325 // printing on the left side for readbility.
326 else if (const VarDecl
*VD
= dyn_cast
<VarDecl
>(D
);
327 VD
&& VD
->getInit() &&
328 VD
->getInitStyle() == VarDecl::CallInit
)
329 AttrLoc
= AttrPrintLoc::Left
;
331 // Only print the side matches the user requested.
332 if ((Loc
& AttrLoc
) != AttrPrintLoc::None
)
333 A
->printPretty(Out
, Policy
);
338 void DeclPrinter::prettyPrintPragmas(Decl
*D
) {
339 if (Policy
.PolishForDeclaration
)
343 AttrVec
&Attrs
= D
->getAttrs();
344 for (auto *A
: Attrs
) {
345 switch (A
->getKind()) {
347 #define PRAGMA_SPELLING_ATTR(X) case attr::X:
348 #include "clang/Basic/AttrList.inc"
349 A
->printPretty(Out
, Policy
);
359 void DeclPrinter::printDeclType(QualType T
, StringRef DeclName
, bool Pack
) {
360 // Normally, a PackExpansionType is written as T[3]... (for instance, as a
361 // template argument), but if it is the type of a declaration, the ellipsis
362 // is placed before the name being declared.
363 if (auto *PET
= T
->getAs
<PackExpansionType
>()) {
365 T
= PET
->getPattern();
367 T
.print(Out
, Policy
, (Pack
? "..." : "") + DeclName
, Indentation
);
370 void DeclPrinter::ProcessDeclGroup(SmallVectorImpl
<Decl
*>& Decls
) {
372 Decl::printGroup(Decls
.data(), Decls
.size(), Out
, Policy
, Indentation
);
378 void DeclPrinter::Print(AccessSpecifier AS
) {
379 const auto AccessSpelling
= getAccessSpelling(AS
);
380 if (AccessSpelling
.empty())
381 llvm_unreachable("No access specifier!");
382 Out
<< AccessSpelling
;
385 void DeclPrinter::PrintConstructorInitializers(CXXConstructorDecl
*CDecl
,
386 std::string
&Proto
) {
387 bool HasInitializerList
= false;
388 for (const auto *BMInitializer
: CDecl
->inits()) {
389 if (BMInitializer
->isInClassMemberInitializer())
391 if (!BMInitializer
->isWritten())
394 if (!HasInitializerList
) {
398 HasInitializerList
= true;
402 if (BMInitializer
->isAnyMemberInitializer()) {
403 FieldDecl
*FD
= BMInitializer
->getAnyMember();
405 } else if (BMInitializer
->isDelegatingInitializer()) {
406 Out
<< CDecl
->getNameAsString();
408 Out
<< QualType(BMInitializer
->getBaseClass(), 0).getAsString(Policy
);
411 if (Expr
*Init
= BMInitializer
->getInit()) {
412 bool OutParens
= !isa
<InitListExpr
>(Init
);
417 if (ExprWithCleanups
*Tmp
= dyn_cast
<ExprWithCleanups
>(Init
))
418 Init
= Tmp
->getSubExpr();
420 Init
= Init
->IgnoreParens();
422 Expr
*SimpleInit
= nullptr;
423 Expr
**Args
= nullptr;
424 unsigned NumArgs
= 0;
425 if (ParenListExpr
*ParenList
= dyn_cast
<ParenListExpr
>(Init
)) {
426 Args
= ParenList
->getExprs();
427 NumArgs
= ParenList
->getNumExprs();
428 } else if (CXXConstructExpr
*Construct
=
429 dyn_cast
<CXXConstructExpr
>(Init
)) {
430 Args
= Construct
->getArgs();
431 NumArgs
= Construct
->getNumArgs();
436 SimpleInit
->printPretty(Out
, nullptr, Policy
, Indentation
, "\n",
439 for (unsigned I
= 0; I
!= NumArgs
; ++I
) {
440 assert(Args
[I
] != nullptr && "Expected non-null Expr");
441 if (isa
<CXXDefaultArgExpr
>(Args
[I
]))
446 Args
[I
]->printPretty(Out
, nullptr, Policy
, Indentation
, "\n",
457 if (BMInitializer
->isPackExpansion())
462 //----------------------------------------------------------------------------
463 // Common C declarations
464 //----------------------------------------------------------------------------
466 void DeclPrinter::VisitDeclContext(DeclContext
*DC
, bool Indent
) {
467 if (Policy
.TerseOutput
)
471 Indentation
+= Policy
.Indentation
;
473 SmallVector
<Decl
*, 2> Decls
;
474 for (DeclContext::decl_iterator D
= DC
->decls_begin(), DEnd
= DC
->decls_end();
477 // Don't print ObjCIvarDecls, as they are printed when visiting the
478 // containing ObjCInterfaceDecl.
479 if (isa
<ObjCIvarDecl
>(*D
))
482 // Skip over implicit declarations in pretty-printing mode.
486 // Don't print implicit specializations, as they are printed when visiting
487 // corresponding templates.
488 if (auto FD
= dyn_cast
<FunctionDecl
>(*D
))
489 if (FD
->getTemplateSpecializationKind() == TSK_ImplicitInstantiation
&&
490 !isa
<ClassTemplateSpecializationDecl
>(DC
))
493 // The next bits of code handle stuff like "struct {int x;} a,b"; we're
494 // forced to merge the declarations because there's no other way to
495 // refer to the struct in question. When that struct is named instead, we
496 // also need to merge to avoid splitting off a stand-alone struct
497 // declaration that produces the warning ext_no_declarators in some
500 // This limited merging is safe without a bunch of other checks because it
501 // only merges declarations directly referring to the tag, not typedefs.
503 // Check whether the current declaration should be grouped with a previous
504 // non-free-standing tag declaration.
505 QualType CurDeclType
= getDeclType(*D
);
506 if (!Decls
.empty() && !CurDeclType
.isNull()) {
507 QualType BaseType
= GetBaseType(CurDeclType
);
508 if (!BaseType
.isNull() && isa
<ElaboratedType
>(BaseType
) &&
509 cast
<ElaboratedType
>(BaseType
)->getOwnedTagDecl() == Decls
[0]) {
515 // If we have a merged group waiting to be handled, handle it now.
517 ProcessDeclGroup(Decls
);
519 // If the current declaration is not a free standing declaration, save it
520 // so we can merge it with the subsequent declaration(s) using it.
521 if (isa
<TagDecl
>(*D
) && !cast
<TagDecl
>(*D
)->isFreeStanding()) {
526 if (isa
<AccessSpecDecl
>(*D
)) {
527 Indentation
-= Policy
.Indentation
;
529 Print(D
->getAccess());
531 Indentation
+= Policy
.Indentation
;
538 // FIXME: Need to be able to tell the DeclPrinter when
539 const char *Terminator
= nullptr;
540 if (isa
<OMPThreadPrivateDecl
>(*D
) || isa
<OMPDeclareReductionDecl
>(*D
) ||
541 isa
<OMPDeclareMapperDecl
>(*D
) || isa
<OMPRequiresDecl
>(*D
) ||
542 isa
<OMPAllocateDecl
>(*D
))
543 Terminator
= nullptr;
544 else if (isa
<ObjCMethodDecl
>(*D
) && cast
<ObjCMethodDecl
>(*D
)->hasBody())
545 Terminator
= nullptr;
546 else if (auto FD
= dyn_cast
<FunctionDecl
>(*D
)) {
547 if (FD
->doesThisDeclarationHaveABody() && !FD
->isDefaulted())
548 Terminator
= nullptr;
551 } else if (auto TD
= dyn_cast
<FunctionTemplateDecl
>(*D
)) {
552 if (TD
->getTemplatedDecl()->doesThisDeclarationHaveABody())
553 Terminator
= nullptr;
556 } else if (isa
<NamespaceDecl
, LinkageSpecDecl
, ObjCImplementationDecl
,
557 ObjCInterfaceDecl
, ObjCProtocolDecl
, ObjCCategoryImplDecl
,
558 ObjCCategoryDecl
, HLSLBufferDecl
>(*D
))
559 Terminator
= nullptr;
560 else if (isa
<EnumConstantDecl
>(*D
)) {
561 DeclContext::decl_iterator Next
= D
;
570 if (!Policy
.TerseOutput
&&
571 ((isa
<FunctionDecl
>(*D
) &&
572 cast
<FunctionDecl
>(*D
)->doesThisDeclarationHaveABody()) ||
573 (isa
<FunctionTemplateDecl
>(*D
) &&
574 cast
<FunctionTemplateDecl
>(*D
)->getTemplatedDecl()->doesThisDeclarationHaveABody())))
575 ; // StmtPrinter already added '\n' after CompoundStmt.
579 // Declare target attribute is special one, natural spelling for the pragma
580 // assumes "ending" construct so print it here.
581 if (D
->hasAttr
<OMPDeclareTargetDeclAttr
>())
582 Out
<< "#pragma omp end declare target\n";
586 ProcessDeclGroup(Decls
);
589 Indentation
-= Policy
.Indentation
;
592 void DeclPrinter::VisitTranslationUnitDecl(TranslationUnitDecl
*D
) {
593 VisitDeclContext(D
, false);
596 void DeclPrinter::VisitTypedefDecl(TypedefDecl
*D
) {
597 if (!Policy
.SuppressSpecifiers
) {
600 if (D
->isModulePrivate())
601 Out
<< "__module_private__ ";
603 QualType Ty
= D
->getTypeSourceInfo()->getType();
604 Ty
.print(Out
, Policy
, D
->getName(), Indentation
);
605 prettyPrintAttributes(D
);
608 void DeclPrinter::VisitTypeAliasDecl(TypeAliasDecl
*D
) {
609 Out
<< "using " << *D
;
610 prettyPrintAttributes(D
);
611 Out
<< " = " << D
->getTypeSourceInfo()->getType().getAsString(Policy
);
614 void DeclPrinter::VisitEnumDecl(EnumDecl
*D
) {
615 if (!Policy
.SuppressSpecifiers
&& D
->isModulePrivate())
616 Out
<< "__module_private__ ";
619 if (D
->isScopedUsingClassTag())
625 prettyPrintAttributes(D
);
627 if (D
->getDeclName())
628 Out
<< ' ' << D
->getDeclName();
631 Out
<< " : " << D
->getIntegerType().stream(Policy
);
633 if (D
->isCompleteDefinition()) {
640 void DeclPrinter::VisitRecordDecl(RecordDecl
*D
) {
641 if (!Policy
.SuppressSpecifiers
&& D
->isModulePrivate())
642 Out
<< "__module_private__ ";
643 Out
<< D
->getKindName();
645 prettyPrintAttributes(D
);
647 if (D
->getIdentifier())
650 if (D
->isCompleteDefinition()) {
657 void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl
*D
) {
659 prettyPrintAttributes(D
);
660 if (Expr
*Init
= D
->getInitExpr()) {
662 Init
->printPretty(Out
, nullptr, Policy
, Indentation
, "\n", &Context
);
666 static void printExplicitSpecifier(ExplicitSpecifier ES
, llvm::raw_ostream
&Out
,
667 PrintingPolicy
&Policy
, unsigned Indentation
,
668 const ASTContext
&Context
) {
669 std::string Proto
= "explicit";
670 llvm::raw_string_ostream
EOut(Proto
);
673 ES
.getExpr()->printPretty(EOut
, nullptr, Policy
, Indentation
, "\n",
682 void DeclPrinter::VisitFunctionDecl(FunctionDecl
*D
) {
683 if (!D
->getDescribedFunctionTemplate() &&
684 !D
->isFunctionTemplateSpecialization())
685 prettyPrintPragmas(D
);
687 if (D
->isFunctionTemplateSpecialization())
688 Out
<< "template<> ";
689 else if (!D
->getDescribedFunctionTemplate()) {
690 for (unsigned I
= 0, NumTemplateParams
= D
->getNumTemplateParameterLists();
691 I
< NumTemplateParams
; ++I
)
692 printTemplateParameters(D
->getTemplateParameterList(I
));
695 std::string LeftsideAttrs
;
696 llvm::raw_string_ostream
LSAS(LeftsideAttrs
);
698 prettyPrintAttributes(D
, LSAS
, AttrPrintLoc::Left
);
700 // prettyPrintAttributes print a space on left side of the attribute.
701 if (LeftsideAttrs
[0] == ' ') {
702 // Skip the space prettyPrintAttributes generated.
703 LeftsideAttrs
.erase(0, LeftsideAttrs
.find_first_not_of(' '));
705 // Add a single space between the attribute and the Decl name.
709 Out
<< LeftsideAttrs
;
711 CXXConstructorDecl
*CDecl
= dyn_cast
<CXXConstructorDecl
>(D
);
712 CXXConversionDecl
*ConversionDecl
= dyn_cast
<CXXConversionDecl
>(D
);
713 CXXDeductionGuideDecl
*GuideDecl
= dyn_cast
<CXXDeductionGuideDecl
>(D
);
714 if (!Policy
.SuppressSpecifiers
) {
715 switch (D
->getStorageClass()) {
717 case SC_Extern
: Out
<< "extern "; break;
718 case SC_Static
: Out
<< "static "; break;
719 case SC_PrivateExtern
: Out
<< "__private_extern__ "; break;
720 case SC_Auto
: case SC_Register
:
721 llvm_unreachable("invalid for functions");
724 if (D
->isInlineSpecified()) Out
<< "inline ";
725 if (D
->isVirtualAsWritten()) Out
<< "virtual ";
726 if (D
->isModulePrivate()) Out
<< "__module_private__ ";
727 if (D
->isConstexprSpecified() && !D
->isExplicitlyDefaulted())
729 if (D
->isConsteval()) Out
<< "consteval ";
730 else if (D
->isImmediateFunction())
732 ExplicitSpecifier ExplicitSpec
= ExplicitSpecifier::getFromDecl(D
);
733 if (ExplicitSpec
.isSpecified())
734 printExplicitSpecifier(ExplicitSpec
, Out
, Policy
, Indentation
, Context
);
737 PrintingPolicy
SubPolicy(Policy
);
738 SubPolicy
.SuppressSpecifiers
= false;
741 if (Policy
.FullyQualifiedName
) {
742 Proto
+= D
->getQualifiedNameAsString();
744 llvm::raw_string_ostream
OS(Proto
);
745 if (!Policy
.SuppressScope
) {
746 if (const NestedNameSpecifier
*NS
= D
->getQualifier()) {
747 NS
->print(OS
, Policy
);
750 D
->getNameInfo().printName(OS
, Policy
);
754 Proto
= GuideDecl
->getDeducedTemplate()->getDeclName().getAsString();
755 if (D
->isFunctionTemplateSpecialization()) {
756 llvm::raw_string_ostream
POut(Proto
);
757 DeclPrinter
TArgPrinter(POut
, SubPolicy
, Context
, Indentation
);
758 const auto *TArgAsWritten
= D
->getTemplateSpecializationArgsAsWritten();
759 if (TArgAsWritten
&& !Policy
.PrintCanonicalTypes
)
760 TArgPrinter
.printTemplateArguments(TArgAsWritten
->arguments(), nullptr);
761 else if (const TemplateArgumentList
*TArgs
=
762 D
->getTemplateSpecializationArgs())
763 TArgPrinter
.printTemplateArguments(TArgs
->asArray(), nullptr);
766 QualType Ty
= D
->getType();
767 while (const ParenType
*PT
= dyn_cast
<ParenType
>(Ty
)) {
768 Proto
= '(' + Proto
+ ')';
769 Ty
= PT
->getInnerType();
772 if (const FunctionType
*AFT
= Ty
->getAs
<FunctionType
>()) {
773 const FunctionProtoType
*FT
= nullptr;
774 if (D
->hasWrittenPrototype())
775 FT
= dyn_cast
<FunctionProtoType
>(AFT
);
779 llvm::raw_string_ostream
POut(Proto
);
780 DeclPrinter
ParamPrinter(POut
, SubPolicy
, Context
, Indentation
);
781 for (unsigned i
= 0, e
= D
->getNumParams(); i
!= e
; ++i
) {
783 ParamPrinter
.VisitParmVarDecl(D
->getParamDecl(i
));
786 if (FT
->isVariadic()) {
787 if (D
->getNumParams()) POut
<< ", ";
789 } else if (!D
->getNumParams() && !Context
.getLangOpts().CPlusPlus
) {
790 // The function has a prototype, so it needs to retain the prototype
794 } else if (D
->doesThisDeclarationHaveABody() && !D
->hasPrototype()) {
795 for (unsigned i
= 0, e
= D
->getNumParams(); i
!= e
; ++i
) {
798 Proto
+= D
->getParamDecl(i
)->getNameAsString();
807 if (FT
->isVolatile())
808 Proto
+= " volatile";
809 if (FT
->isRestrict())
810 Proto
+= " restrict";
812 switch (FT
->getRefQualifier()) {
824 if (FT
&& FT
->hasDynamicExceptionSpec()) {
826 if (FT
->getExceptionSpecType() == EST_MSAny
)
829 for (unsigned I
= 0, N
= FT
->getNumExceptions(); I
!= N
; ++I
) {
833 Proto
+= FT
->getExceptionType(I
).getAsString(SubPolicy
);
836 } else if (FT
&& isNoexceptExceptionSpec(FT
->getExceptionSpecType())) {
837 Proto
+= " noexcept";
838 if (isComputedNoexcept(FT
->getExceptionSpecType())) {
840 llvm::raw_string_ostream
EOut(Proto
);
841 FT
->getNoexceptExpr()->printPretty(EOut
, nullptr, SubPolicy
,
842 Indentation
, "\n", &Context
);
849 if (!Policy
.TerseOutput
)
850 PrintConstructorInitializers(CDecl
, Proto
);
851 } else if (!ConversionDecl
&& !isa
<CXXDestructorDecl
>(D
)) {
852 if (FT
&& FT
->hasTrailingReturn()) {
855 Out
<< Proto
<< " -> ";
858 AFT
->getReturnType().print(Out
, Policy
, Proto
);
863 if (Expr
*TrailingRequiresClause
= D
->getTrailingRequiresClause()) {
865 TrailingRequiresClause
->printPretty(Out
, nullptr, SubPolicy
, Indentation
,
869 Ty
.print(Out
, Policy
, Proto
);
872 prettyPrintAttributes(D
, Out
, AttrPrintLoc::Right
);
876 else if (D
->isDeletedAsWritten())
878 else if (D
->isExplicitlyDefaulted())
880 else if (D
->doesThisDeclarationHaveABody()) {
881 if (!Policy
.TerseOutput
) {
882 if (!D
->hasPrototype() && D
->getNumParams()) {
883 // This is a K&R function definition, so we need to print the
886 DeclPrinter
ParamPrinter(Out
, SubPolicy
, Context
, Indentation
);
887 Indentation
+= Policy
.Indentation
;
888 for (unsigned i
= 0, e
= D
->getNumParams(); i
!= e
; ++i
) {
890 ParamPrinter
.VisitParmVarDecl(D
->getParamDecl(i
));
893 Indentation
-= Policy
.Indentation
;
897 D
->getBody()->printPrettyControlled(Out
, nullptr, SubPolicy
, Indentation
, "\n",
900 if (!Policy
.TerseOutput
&& isa
<CXXConstructorDecl
>(*D
))
906 void DeclPrinter::VisitFriendDecl(FriendDecl
*D
) {
907 if (TypeSourceInfo
*TSI
= D
->getFriendType()) {
908 unsigned NumTPLists
= D
->getFriendTypeNumTemplateParameterLists();
909 for (unsigned i
= 0; i
< NumTPLists
; ++i
)
910 printTemplateParameters(D
->getFriendTypeTemplateParameterList(i
));
912 Out
<< " " << TSI
->getType().getAsString(Policy
);
914 else if (FunctionDecl
*FD
=
915 dyn_cast
<FunctionDecl
>(D
->getFriendDecl())) {
917 VisitFunctionDecl(FD
);
919 else if (FunctionTemplateDecl
*FTD
=
920 dyn_cast
<FunctionTemplateDecl
>(D
->getFriendDecl())) {
922 VisitFunctionTemplateDecl(FTD
);
924 else if (ClassTemplateDecl
*CTD
=
925 dyn_cast
<ClassTemplateDecl
>(D
->getFriendDecl())) {
927 VisitRedeclarableTemplateDecl(CTD
);
931 void DeclPrinter::VisitFieldDecl(FieldDecl
*D
) {
932 // FIXME: add printing of pragma attributes if required.
933 if (!Policy
.SuppressSpecifiers
&& D
->isMutable())
935 if (!Policy
.SuppressSpecifiers
&& D
->isModulePrivate())
936 Out
<< "__module_private__ ";
938 Out
<< D
->getASTContext().getUnqualifiedObjCPointerType(D
->getType()).
939 stream(Policy
, D
->getName(), Indentation
);
941 if (D
->isBitField()) {
943 D
->getBitWidth()->printPretty(Out
, nullptr, Policy
, Indentation
, "\n",
947 Expr
*Init
= D
->getInClassInitializer();
948 if (!Policy
.SuppressInitializers
&& Init
) {
949 if (D
->getInClassInitStyle() == ICIS_ListInit
)
953 Init
->printPretty(Out
, nullptr, Policy
, Indentation
, "\n", &Context
);
955 prettyPrintAttributes(D
);
958 void DeclPrinter::VisitLabelDecl(LabelDecl
*D
) {
962 void DeclPrinter::VisitVarDecl(VarDecl
*D
) {
963 prettyPrintPragmas(D
);
965 if (const auto *Param
= dyn_cast
<ParmVarDecl
>(D
);
966 Param
&& Param
->isExplicitObjectParameter())
969 std::string LeftSide
;
970 llvm::raw_string_ostream
LeftSideStream(LeftSide
);
972 // Print attributes that should be placed on the left, such as __declspec.
973 prettyPrintAttributes(D
, LeftSideStream
, AttrPrintLoc::Left
);
975 // prettyPrintAttributes print a space on left side of the attribute.
976 if (LeftSide
[0] == ' ') {
977 // Skip the space prettyPrintAttributes generated.
978 LeftSide
.erase(0, LeftSide
.find_first_not_of(' '));
980 // Add a single space between the attribute and the Decl name.
981 LeftSideStream
<< ' ';
986 QualType T
= D
->getTypeSourceInfo()
987 ? D
->getTypeSourceInfo()->getType()
988 : D
->getASTContext().getUnqualifiedObjCPointerType(D
->getType());
990 if (!Policy
.SuppressSpecifiers
) {
991 StorageClass SC
= D
->getStorageClass();
993 Out
<< VarDecl::getStorageClassSpecifierString(SC
) << " ";
995 switch (D
->getTSCSpec()) {
996 case TSCS_unspecified
:
1001 case TSCS__Thread_local
:
1002 Out
<< "_Thread_local ";
1004 case TSCS_thread_local
:
1005 Out
<< "thread_local ";
1009 if (D
->isModulePrivate())
1010 Out
<< "__module_private__ ";
1012 if (D
->isConstexpr()) {
1013 Out
<< "constexpr ";
1014 T
.removeLocalConst();
1020 Name
= (isa
<ParmVarDecl
>(D
) && Policy
.CleanUglifiedParameters
&&
1022 ? D
->getIdentifier()->deuglifiedName()
1025 printDeclType(T
, Name
);
1027 // Print the attributes that should be placed right before the end of the
1029 prettyPrintAttributes(D
, Out
, AttrPrintLoc::Right
);
1031 Expr
*Init
= D
->getInit();
1032 if (!Policy
.SuppressInitializers
&& Init
) {
1033 bool ImplicitInit
= false;
1034 if (D
->isCXXForRangeDecl()) {
1035 // FIXME: We should print the range expression instead.
1036 ImplicitInit
= true;
1037 } else if (CXXConstructExpr
*Construct
=
1038 dyn_cast
<CXXConstructExpr
>(Init
->IgnoreImplicit())) {
1039 if (D
->getInitStyle() == VarDecl::CallInit
&&
1040 !Construct
->isListInitialization()) {
1041 ImplicitInit
= Construct
->getNumArgs() == 0 ||
1042 Construct
->getArg(0)->isDefaultArgument();
1045 if (!ImplicitInit
) {
1046 if ((D
->getInitStyle() == VarDecl::CallInit
) && !isa
<ParenListExpr
>(Init
))
1048 else if (D
->getInitStyle() == VarDecl::CInit
) {
1051 PrintingPolicy
SubPolicy(Policy
);
1052 SubPolicy
.SuppressSpecifiers
= false;
1053 SubPolicy
.IncludeTagDefinition
= false;
1054 Init
->printPretty(Out
, nullptr, SubPolicy
, Indentation
, "\n", &Context
);
1055 if ((D
->getInitStyle() == VarDecl::CallInit
) && !isa
<ParenListExpr
>(Init
))
1061 void DeclPrinter::VisitParmVarDecl(ParmVarDecl
*D
) {
1065 void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl
*D
) {
1067 D
->getAsmString()->printPretty(Out
, nullptr, Policy
, Indentation
, "\n",
1072 void DeclPrinter::VisitTopLevelStmtDecl(TopLevelStmtDecl
*D
) {
1073 assert(D
->getStmt());
1074 D
->getStmt()->printPretty(Out
, nullptr, Policy
, Indentation
, "\n", &Context
);
1077 void DeclPrinter::VisitImportDecl(ImportDecl
*D
) {
1078 Out
<< "@import " << D
->getImportedModule()->getFullModuleName()
1082 void DeclPrinter::VisitStaticAssertDecl(StaticAssertDecl
*D
) {
1083 Out
<< "static_assert(";
1084 D
->getAssertExpr()->printPretty(Out
, nullptr, Policy
, Indentation
, "\n",
1086 if (Expr
*E
= D
->getMessage()) {
1088 E
->printPretty(Out
, nullptr, Policy
, Indentation
, "\n", &Context
);
1093 //----------------------------------------------------------------------------
1095 //----------------------------------------------------------------------------
1096 void DeclPrinter::VisitNamespaceDecl(NamespaceDecl
*D
) {
1100 Out
<< "namespace ";
1101 if (D
->getDeclName())
1102 Out
<< D
->getDeclName() << ' ';
1105 VisitDeclContext(D
);
1109 void DeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl
*D
) {
1110 Out
<< "using namespace ";
1111 if (D
->getQualifier())
1112 D
->getQualifier()->print(Out
, Policy
);
1113 Out
<< *D
->getNominatedNamespaceAsWritten();
1116 void DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl
*D
) {
1117 Out
<< "namespace " << *D
<< " = ";
1118 if (D
->getQualifier())
1119 D
->getQualifier()->print(Out
, Policy
);
1120 Out
<< *D
->getAliasedNamespace();
1123 void DeclPrinter::VisitEmptyDecl(EmptyDecl
*D
) {
1124 prettyPrintAttributes(D
);
1127 void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl
*D
) {
1128 // FIXME: add printing of pragma attributes if required.
1129 if (!Policy
.SuppressSpecifiers
&& D
->isModulePrivate())
1130 Out
<< "__module_private__ ";
1131 Out
<< D
->getKindName();
1133 prettyPrintAttributes(D
);
1135 if (D
->getIdentifier()) {
1137 if (auto *NNS
= D
->getQualifier())
1138 NNS
->print(Out
, Policy
);
1141 if (auto S
= dyn_cast
<ClassTemplateSpecializationDecl
>(D
)) {
1142 ArrayRef
<TemplateArgument
> Args
= S
->getTemplateArgs().asArray();
1143 if (!Policy
.PrintCanonicalTypes
)
1144 if (const auto* TSI
= S
->getTypeAsWritten())
1145 if (const auto *TST
=
1146 dyn_cast
<TemplateSpecializationType
>(TSI
->getType()))
1147 Args
= TST
->template_arguments();
1148 printTemplateArguments(
1149 Args
, S
->getSpecializedTemplate()->getTemplateParameters());
1153 if (D
->hasDefinition()) {
1154 if (D
->hasAttr
<FinalAttr
>()) {
1159 if (D
->isCompleteDefinition()) {
1160 // Print the base classes
1161 if (D
->getNumBases()) {
1163 for (CXXRecordDecl::base_class_iterator Base
= D
->bases_begin(),
1164 BaseEnd
= D
->bases_end(); Base
!= BaseEnd
; ++Base
) {
1165 if (Base
!= D
->bases_begin())
1168 if (Base
->isVirtual())
1171 AccessSpecifier AS
= Base
->getAccessSpecifierAsWritten();
1172 if (AS
!= AS_none
) {
1176 Out
<< Base
->getType().getAsString(Policy
);
1178 if (Base
->isPackExpansion())
1183 // Print the class definition
1184 // FIXME: Doesn't print access specifiers, e.g., "public:"
1185 if (Policy
.TerseOutput
) {
1189 VisitDeclContext(D
);
1195 void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl
*D
) {
1197 if (D
->getLanguage() == LinkageSpecLanguageIDs::C
)
1200 assert(D
->getLanguage() == LinkageSpecLanguageIDs::CXX
&&
1201 "unknown language in linkage specification");
1205 Out
<< "extern \"" << l
<< "\" ";
1206 if (D
->hasBraces()) {
1208 VisitDeclContext(D
);
1211 Visit(*D
->decls_begin());
1214 void DeclPrinter::printTemplateParameters(const TemplateParameterList
*Params
,
1215 bool OmitTemplateKW
) {
1218 if (!OmitTemplateKW
)
1222 bool NeedComma
= false;
1223 for (const Decl
*Param
: *Params
) {
1224 if (Param
->isImplicit())
1232 if (const auto *TTP
= dyn_cast
<TemplateTypeParmDecl
>(Param
)) {
1233 VisitTemplateTypeParmDecl(TTP
);
1234 } else if (auto NTTP
= dyn_cast
<NonTypeTemplateParmDecl
>(Param
)) {
1235 VisitNonTypeTemplateParmDecl(NTTP
);
1236 } else if (auto TTPD
= dyn_cast
<TemplateTemplateParmDecl
>(Param
)) {
1237 VisitTemplateDecl(TTPD
);
1238 // FIXME: print the default argument, if present.
1243 if (!OmitTemplateKW
)
1247 void DeclPrinter::printTemplateArguments(ArrayRef
<TemplateArgument
> Args
,
1248 const TemplateParameterList
*Params
) {
1250 for (size_t I
= 0, E
= Args
.size(); I
< E
; ++I
) {
1254 Args
[I
].print(Policy
, Out
, /*IncludeType*/ true);
1256 Args
[I
].print(Policy
, Out
,
1257 TemplateParameterList::shouldIncludeTypeForArgument(
1258 Policy
, Params
, I
));
1263 void DeclPrinter::printTemplateArguments(ArrayRef
<TemplateArgumentLoc
> Args
,
1264 const TemplateParameterList
*Params
) {
1266 for (size_t I
= 0, E
= Args
.size(); I
< E
; ++I
) {
1270 Args
[I
].getArgument().print(Policy
, Out
, /*IncludeType*/ true);
1272 Args
[I
].getArgument().print(
1274 TemplateParameterList::shouldIncludeTypeForArgument(Policy
, Params
,
1280 void DeclPrinter::VisitTemplateDecl(const TemplateDecl
*D
) {
1281 printTemplateParameters(D
->getTemplateParameters());
1283 if (const TemplateTemplateParmDecl
*TTP
=
1284 dyn_cast
<TemplateTemplateParmDecl
>(D
)) {
1287 if (TTP
->isParameterPack())
1289 else if (TTP
->getDeclName())
1292 if (TTP
->getDeclName()) {
1293 if (Policy
.CleanUglifiedParameters
&& TTP
->getIdentifier())
1294 Out
<< TTP
->getIdentifier()->deuglifiedName();
1296 Out
<< TTP
->getDeclName();
1298 } else if (auto *TD
= D
->getTemplatedDecl())
1300 else if (const auto *Concept
= dyn_cast
<ConceptDecl
>(D
)) {
1301 Out
<< "concept " << Concept
->getName() << " = " ;
1302 Concept
->getConstraintExpr()->printPretty(Out
, nullptr, Policy
, Indentation
,
1307 void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl
*D
) {
1308 prettyPrintPragmas(D
->getTemplatedDecl());
1309 // Print any leading template parameter lists.
1310 if (const FunctionDecl
*FD
= D
->getTemplatedDecl()) {
1311 for (unsigned I
= 0, NumTemplateParams
= FD
->getNumTemplateParameterLists();
1312 I
< NumTemplateParams
; ++I
)
1313 printTemplateParameters(FD
->getTemplateParameterList(I
));
1315 VisitRedeclarableTemplateDecl(D
);
1316 // Declare target attribute is special one, natural spelling for the pragma
1317 // assumes "ending" construct so print it here.
1318 if (D
->getTemplatedDecl()->hasAttr
<OMPDeclareTargetDeclAttr
>())
1319 Out
<< "#pragma omp end declare target\n";
1321 // Never print "instantiations" for deduction guides (they don't really
1323 if (PrintInstantiation
&&
1324 !isa
<CXXDeductionGuideDecl
>(D
->getTemplatedDecl())) {
1325 FunctionDecl
*PrevDecl
= D
->getTemplatedDecl();
1326 const FunctionDecl
*Def
;
1327 if (PrevDecl
->isDefined(Def
) && Def
!= PrevDecl
)
1329 for (auto *I
: D
->specializations())
1330 if (I
->getTemplateSpecializationKind() == TSK_ImplicitInstantiation
) {
1331 if (!PrevDecl
->isThisDeclarationADefinition())
1334 prettyPrintPragmas(I
);
1340 void DeclPrinter::VisitClassTemplateDecl(ClassTemplateDecl
*D
) {
1341 VisitRedeclarableTemplateDecl(D
);
1343 if (PrintInstantiation
) {
1344 for (auto *I
: D
->specializations())
1345 if (I
->getSpecializationKind() == TSK_ImplicitInstantiation
) {
1346 if (D
->isThisDeclarationADefinition())
1355 void DeclPrinter::VisitClassTemplateSpecializationDecl(
1356 ClassTemplateSpecializationDecl
*D
) {
1357 Out
<< "template<> ";
1358 VisitCXXRecordDecl(D
);
1361 void DeclPrinter::VisitClassTemplatePartialSpecializationDecl(
1362 ClassTemplatePartialSpecializationDecl
*D
) {
1363 printTemplateParameters(D
->getTemplateParameters());
1364 VisitCXXRecordDecl(D
);
1367 //----------------------------------------------------------------------------
1368 // Objective-C declarations
1369 //----------------------------------------------------------------------------
1371 void DeclPrinter::PrintObjCMethodType(ASTContext
&Ctx
,
1372 Decl::ObjCDeclQualifier Quals
,
1375 if (Quals
& Decl::ObjCDeclQualifier::OBJC_TQ_In
)
1377 if (Quals
& Decl::ObjCDeclQualifier::OBJC_TQ_Inout
)
1379 if (Quals
& Decl::ObjCDeclQualifier::OBJC_TQ_Out
)
1381 if (Quals
& Decl::ObjCDeclQualifier::OBJC_TQ_Bycopy
)
1383 if (Quals
& Decl::ObjCDeclQualifier::OBJC_TQ_Byref
)
1385 if (Quals
& Decl::ObjCDeclQualifier::OBJC_TQ_Oneway
)
1387 if (Quals
& Decl::ObjCDeclQualifier::OBJC_TQ_CSNullability
) {
1388 if (auto nullability
= AttributedType::stripOuterNullability(T
))
1389 Out
<< getNullabilitySpelling(*nullability
, true) << ' ';
1392 Out
<< Ctx
.getUnqualifiedObjCPointerType(T
).getAsString(Policy
);
1396 void DeclPrinter::PrintObjCTypeParams(ObjCTypeParamList
*Params
) {
1398 unsigned First
= true;
1399 for (auto *Param
: *Params
) {
1406 switch (Param
->getVariance()) {
1407 case ObjCTypeParamVariance::Invariant
:
1410 case ObjCTypeParamVariance::Covariant
:
1411 Out
<< "__covariant ";
1414 case ObjCTypeParamVariance::Contravariant
:
1415 Out
<< "__contravariant ";
1419 Out
<< Param
->getDeclName();
1421 if (Param
->hasExplicitBound()) {
1422 Out
<< " : " << Param
->getUnderlyingType().getAsString(Policy
);
1428 void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl
*OMD
) {
1429 if (OMD
->isInstanceMethod())
1433 if (!OMD
->getReturnType().isNull()) {
1434 PrintObjCMethodType(OMD
->getASTContext(), OMD
->getObjCDeclQualifier(),
1435 OMD
->getReturnType());
1438 std::string name
= OMD
->getSelector().getAsString();
1439 std::string::size_type pos
, lastPos
= 0;
1440 for (const auto *PI
: OMD
->parameters()) {
1441 // FIXME: selector is missing here!
1442 pos
= name
.find_first_of(':', lastPos
);
1445 Out
<< name
.substr(lastPos
, pos
- lastPos
) << ':';
1446 PrintObjCMethodType(OMD
->getASTContext(),
1447 PI
->getObjCDeclQualifier(),
1453 if (OMD
->param_begin() == OMD
->param_end())
1456 if (OMD
->isVariadic())
1459 prettyPrintAttributes(OMD
);
1461 if (OMD
->getBody() && !Policy
.TerseOutput
) {
1463 OMD
->getBody()->printPretty(Out
, nullptr, Policy
, Indentation
, "\n",
1466 else if (Policy
.PolishForDeclaration
)
1470 void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl
*OID
) {
1471 std::string I
= OID
->getNameAsString();
1472 ObjCInterfaceDecl
*SID
= OID
->getSuperClass();
1474 bool eolnOut
= false;
1476 Out
<< "@implementation " << I
<< " : " << *SID
;
1478 Out
<< "@implementation " << I
;
1480 if (OID
->ivar_size() > 0) {
1483 Indentation
+= Policy
.Indentation
;
1484 for (const auto *I
: OID
->ivars()) {
1485 Indent() << I
->getASTContext().getUnqualifiedObjCPointerType(I
->getType()).
1486 getAsString(Policy
) << ' ' << *I
<< ";\n";
1488 Indentation
-= Policy
.Indentation
;
1491 else if (SID
|| (OID
->decls_begin() != OID
->decls_end())) {
1495 VisitDeclContext(OID
, false);
1501 void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl
*OID
) {
1502 std::string I
= OID
->getNameAsString();
1503 ObjCInterfaceDecl
*SID
= OID
->getSuperClass();
1505 if (!OID
->isThisDeclarationADefinition()) {
1506 Out
<< "@class " << I
;
1508 if (auto TypeParams
= OID
->getTypeParamListAsWritten()) {
1509 PrintObjCTypeParams(TypeParams
);
1515 bool eolnOut
= false;
1516 Out
<< "@interface " << I
;
1518 if (auto TypeParams
= OID
->getTypeParamListAsWritten()) {
1519 PrintObjCTypeParams(TypeParams
);
1523 Out
<< " : " << QualType(OID
->getSuperClassType(), 0).getAsString(Policy
);
1526 const ObjCList
<ObjCProtocolDecl
> &Protocols
= OID
->getReferencedProtocols();
1527 if (!Protocols
.empty()) {
1528 for (ObjCList
<ObjCProtocolDecl
>::iterator I
= Protocols
.begin(),
1529 E
= Protocols
.end(); I
!= E
; ++I
)
1530 Out
<< (I
== Protocols
.begin() ? '<' : ',') << **I
;
1534 if (OID
->ivar_size() > 0) {
1537 Indentation
+= Policy
.Indentation
;
1538 for (const auto *I
: OID
->ivars()) {
1539 Indent() << I
->getASTContext()
1540 .getUnqualifiedObjCPointerType(I
->getType())
1541 .getAsString(Policy
) << ' ' << *I
<< ";\n";
1543 Indentation
-= Policy
.Indentation
;
1546 else if (SID
|| (OID
->decls_begin() != OID
->decls_end())) {
1551 VisitDeclContext(OID
, false);
1555 // FIXME: implement the rest...
1558 void DeclPrinter::VisitObjCProtocolDecl(ObjCProtocolDecl
*PID
) {
1559 if (!PID
->isThisDeclarationADefinition()) {
1560 Out
<< "@protocol " << *PID
<< ";\n";
1564 const ObjCList
<ObjCProtocolDecl
> &Protocols
= PID
->getReferencedProtocols();
1565 if (!Protocols
.empty()) {
1566 Out
<< "@protocol " << *PID
;
1567 for (ObjCList
<ObjCProtocolDecl
>::iterator I
= Protocols
.begin(),
1568 E
= Protocols
.end(); I
!= E
; ++I
)
1569 Out
<< (I
== Protocols
.begin() ? '<' : ',') << **I
;
1572 Out
<< "@protocol " << *PID
<< '\n';
1573 VisitDeclContext(PID
, false);
1577 void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl
*PID
) {
1578 Out
<< "@implementation ";
1579 if (const auto *CID
= PID
->getClassInterface())
1582 Out
<< "<<error-type>>";
1583 Out
<< '(' << *PID
<< ")\n";
1585 VisitDeclContext(PID
, false);
1587 // FIXME: implement the rest...
1590 void DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl
*PID
) {
1591 Out
<< "@interface ";
1592 if (const auto *CID
= PID
->getClassInterface())
1595 Out
<< "<<error-type>>";
1596 if (auto TypeParams
= PID
->getTypeParamList()) {
1597 PrintObjCTypeParams(TypeParams
);
1599 Out
<< "(" << *PID
<< ")\n";
1600 if (PID
->ivar_size() > 0) {
1602 Indentation
+= Policy
.Indentation
;
1603 for (const auto *I
: PID
->ivars())
1604 Indent() << I
->getASTContext().getUnqualifiedObjCPointerType(I
->getType()).
1605 getAsString(Policy
) << ' ' << *I
<< ";\n";
1606 Indentation
-= Policy
.Indentation
;
1610 VisitDeclContext(PID
, false);
1613 // FIXME: implement the rest...
1616 void DeclPrinter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl
*AID
) {
1617 Out
<< "@compatibility_alias " << *AID
1618 << ' ' << *AID
->getClassInterface() << ";\n";
1621 /// PrintObjCPropertyDecl - print a property declaration.
1623 /// Print attributes in the following order:
1625 /// - nonatomic | atomic
1626 /// - assign | retain | strong | copy | weak | unsafe_unretained
1627 /// - readwrite | readonly
1628 /// - getter & setter
1630 void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl
*PDecl
) {
1631 if (PDecl
->getPropertyImplementation() == ObjCPropertyDecl::Required
)
1632 Out
<< "@required\n";
1633 else if (PDecl
->getPropertyImplementation() == ObjCPropertyDecl::Optional
)
1634 Out
<< "@optional\n";
1636 QualType T
= PDecl
->getType();
1639 if (PDecl
->getPropertyAttributes() != ObjCPropertyAttribute::kind_noattr
) {
1642 if (PDecl
->getPropertyAttributes() & ObjCPropertyAttribute::kind_class
) {
1643 Out
<< (first
? "" : ", ") << "class";
1647 if (PDecl
->getPropertyAttributes() & ObjCPropertyAttribute::kind_direct
) {
1648 Out
<< (first
? "" : ", ") << "direct";
1652 if (PDecl
->getPropertyAttributes() &
1653 ObjCPropertyAttribute::kind_nonatomic
) {
1654 Out
<< (first
? "" : ", ") << "nonatomic";
1657 if (PDecl
->getPropertyAttributes() & ObjCPropertyAttribute::kind_atomic
) {
1658 Out
<< (first
? "" : ", ") << "atomic";
1662 if (PDecl
->getPropertyAttributes() & ObjCPropertyAttribute::kind_assign
) {
1663 Out
<< (first
? "" : ", ") << "assign";
1666 if (PDecl
->getPropertyAttributes() & ObjCPropertyAttribute::kind_retain
) {
1667 Out
<< (first
? "" : ", ") << "retain";
1671 if (PDecl
->getPropertyAttributes() & ObjCPropertyAttribute::kind_strong
) {
1672 Out
<< (first
? "" : ", ") << "strong";
1675 if (PDecl
->getPropertyAttributes() & ObjCPropertyAttribute::kind_copy
) {
1676 Out
<< (first
? "" : ", ") << "copy";
1679 if (PDecl
->getPropertyAttributes() & ObjCPropertyAttribute::kind_weak
) {
1680 Out
<< (first
? "" : ", ") << "weak";
1683 if (PDecl
->getPropertyAttributes() &
1684 ObjCPropertyAttribute::kind_unsafe_unretained
) {
1685 Out
<< (first
? "" : ", ") << "unsafe_unretained";
1689 if (PDecl
->getPropertyAttributes() &
1690 ObjCPropertyAttribute::kind_readwrite
) {
1691 Out
<< (first
? "" : ", ") << "readwrite";
1694 if (PDecl
->getPropertyAttributes() & ObjCPropertyAttribute::kind_readonly
) {
1695 Out
<< (first
? "" : ", ") << "readonly";
1699 if (PDecl
->getPropertyAttributes() & ObjCPropertyAttribute::kind_getter
) {
1700 Out
<< (first
? "" : ", ") << "getter = ";
1701 PDecl
->getGetterName().print(Out
);
1704 if (PDecl
->getPropertyAttributes() & ObjCPropertyAttribute::kind_setter
) {
1705 Out
<< (first
? "" : ", ") << "setter = ";
1706 PDecl
->getSetterName().print(Out
);
1710 if (PDecl
->getPropertyAttributes() &
1711 ObjCPropertyAttribute::kind_nullability
) {
1712 if (auto nullability
= AttributedType::stripOuterNullability(T
)) {
1713 if (*nullability
== NullabilityKind::Unspecified
&&
1714 (PDecl
->getPropertyAttributes() &
1715 ObjCPropertyAttribute::kind_null_resettable
)) {
1716 Out
<< (first
? "" : ", ") << "null_resettable";
1718 Out
<< (first
? "" : ", ")
1719 << getNullabilitySpelling(*nullability
, true);
1725 (void) first
; // Silence dead store warning due to idiomatic code.
1728 std::string TypeStr
= PDecl
->getASTContext().getUnqualifiedObjCPointerType(T
).
1729 getAsString(Policy
);
1730 Out
<< ' ' << TypeStr
;
1731 if (!StringRef(TypeStr
).endswith("*"))
1734 if (Policy
.PolishForDeclaration
)
1738 void DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl
*PID
) {
1739 if (PID
->getPropertyImplementation() == ObjCPropertyImplDecl::Synthesize
)
1740 Out
<< "@synthesize ";
1743 Out
<< *PID
->getPropertyDecl();
1744 if (PID
->getPropertyIvarDecl())
1745 Out
<< '=' << *PID
->getPropertyIvarDecl();
1748 void DeclPrinter::VisitUsingDecl(UsingDecl
*D
) {
1749 if (!D
->isAccessDeclaration())
1751 if (D
->hasTypename())
1753 D
->getQualifier()->print(Out
, Policy
);
1755 // Use the correct record name when the using declaration is used for
1756 // inheriting constructors.
1757 for (const auto *Shadow
: D
->shadows()) {
1758 if (const auto *ConstructorShadow
=
1759 dyn_cast
<ConstructorUsingShadowDecl
>(Shadow
)) {
1760 assert(Shadow
->getDeclContext() == ConstructorShadow
->getDeclContext());
1761 Out
<< *ConstructorShadow
->getNominatedBaseClass();
1768 void DeclPrinter::VisitUsingEnumDecl(UsingEnumDecl
*D
) {
1769 Out
<< "using enum " << D
->getEnumDecl();
1773 DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl
*D
) {
1774 Out
<< "using typename ";
1775 D
->getQualifier()->print(Out
, Policy
);
1776 Out
<< D
->getDeclName();
1779 void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl
*D
) {
1780 if (!D
->isAccessDeclaration())
1782 D
->getQualifier()->print(Out
, Policy
);
1783 Out
<< D
->getDeclName();
1786 void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl
*D
) {
1790 void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl
*D
) {
1791 Out
<< "#pragma omp threadprivate";
1792 if (!D
->varlist_empty()) {
1793 for (OMPThreadPrivateDecl::varlist_iterator I
= D
->varlist_begin(),
1794 E
= D
->varlist_end();
1796 Out
<< (I
== D
->varlist_begin() ? '(' : ',');
1797 NamedDecl
*ND
= cast
<DeclRefExpr
>(*I
)->getDecl();
1798 ND
->printQualifiedName(Out
);
1804 void DeclPrinter::VisitHLSLBufferDecl(HLSLBufferDecl
*D
) {
1812 prettyPrintAttributes(D
);
1815 VisitDeclContext(D
);
1819 void DeclPrinter::VisitOMPAllocateDecl(OMPAllocateDecl
*D
) {
1820 Out
<< "#pragma omp allocate";
1821 if (!D
->varlist_empty()) {
1822 for (OMPAllocateDecl::varlist_iterator I
= D
->varlist_begin(),
1823 E
= D
->varlist_end();
1825 Out
<< (I
== D
->varlist_begin() ? '(' : ',');
1826 NamedDecl
*ND
= cast
<DeclRefExpr
>(*I
)->getDecl();
1827 ND
->printQualifiedName(Out
);
1831 if (!D
->clauselist_empty()) {
1832 OMPClausePrinter
Printer(Out
, Policy
);
1833 for (OMPClause
*C
: D
->clauselists()) {
1840 void DeclPrinter::VisitOMPRequiresDecl(OMPRequiresDecl
*D
) {
1841 Out
<< "#pragma omp requires ";
1842 if (!D
->clauselist_empty()) {
1843 OMPClausePrinter
Printer(Out
, Policy
);
1844 for (auto I
= D
->clauselist_begin(), E
= D
->clauselist_end(); I
!= E
; ++I
)
1849 void DeclPrinter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl
*D
) {
1850 if (!D
->isInvalidDecl()) {
1851 Out
<< "#pragma omp declare reduction (";
1852 if (D
->getDeclName().getNameKind() == DeclarationName::CXXOperatorName
) {
1853 const char *OpName
=
1854 getOperatorSpelling(D
->getDeclName().getCXXOverloadedOperator());
1855 assert(OpName
&& "not an overloaded operator");
1858 assert(D
->getDeclName().isIdentifier());
1859 D
->printName(Out
, Policy
);
1862 D
->getType().print(Out
, Policy
);
1864 D
->getCombiner()->printPretty(Out
, nullptr, Policy
, 0, "\n", &Context
);
1866 if (auto *Init
= D
->getInitializer()) {
1867 Out
<< " initializer(";
1868 switch (D
->getInitializerKind()) {
1869 case OMPDeclareReductionInitKind::Direct
:
1872 case OMPDeclareReductionInitKind::Copy
:
1873 Out
<< "omp_priv = ";
1875 case OMPDeclareReductionInitKind::Call
:
1878 Init
->printPretty(Out
, nullptr, Policy
, 0, "\n", &Context
);
1879 if (D
->getInitializerKind() == OMPDeclareReductionInitKind::Direct
)
1886 void DeclPrinter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl
*D
) {
1887 if (!D
->isInvalidDecl()) {
1888 Out
<< "#pragma omp declare mapper (";
1889 D
->printName(Out
, Policy
);
1891 D
->getType().print(Out
, Policy
);
1893 Out
<< D
->getVarName();
1895 if (!D
->clauselist_empty()) {
1896 OMPClausePrinter
Printer(Out
, Policy
);
1897 for (auto *C
: D
->clauselists()) {
1905 void DeclPrinter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl
*D
) {
1906 D
->getInit()->printPretty(Out
, nullptr, Policy
, Indentation
, "\n", &Context
);
1909 void DeclPrinter::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl
*TTP
) {
1910 if (const TypeConstraint
*TC
= TTP
->getTypeConstraint())
1911 TC
->print(Out
, Policy
);
1912 else if (TTP
->wasDeclaredWithTypename())
1917 if (TTP
->isParameterPack())
1919 else if (TTP
->getDeclName())
1922 if (TTP
->getDeclName()) {
1923 if (Policy
.CleanUglifiedParameters
&& TTP
->getIdentifier())
1924 Out
<< TTP
->getIdentifier()->deuglifiedName();
1926 Out
<< TTP
->getDeclName();
1929 if (TTP
->hasDefaultArgument()) {
1931 Out
<< TTP
->getDefaultArgument().getAsString(Policy
);
1935 void DeclPrinter::VisitNonTypeTemplateParmDecl(
1936 const NonTypeTemplateParmDecl
*NTTP
) {
1938 if (IdentifierInfo
*II
= NTTP
->getIdentifier())
1940 Policy
.CleanUglifiedParameters
? II
->deuglifiedName() : II
->getName();
1941 printDeclType(NTTP
->getType(), Name
, NTTP
->isParameterPack());
1943 if (NTTP
->hasDefaultArgument()) {
1945 NTTP
->getDefaultArgument()->printPretty(Out
, nullptr, Policy
, Indentation
,