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