clang 24.0.0git
DeclPrinter.cpp
Go to the documentation of this file.
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//===----------------------------------------------------------------------===//
14#include "clang/AST/Attr.h"
15#include "clang/AST/Decl.h"
16#include "clang/AST/DeclCXX.h"
17#include "clang/AST/DeclObjC.h"
20#include "clang/AST/Expr.h"
21#include "clang/AST/ExprCXX.h"
23#include "clang/Basic/Module.h"
25#include "llvm/ADT/StringExtras.h"
26#include "llvm/Support/raw_ostream.h"
27using namespace clang;
28
29namespace {
30 class DeclPrinter : public DeclVisitor<DeclPrinter> {
31 raw_ostream &Out;
32 PrintingPolicy Policy;
33 const ASTContext &Context;
34 unsigned Indentation;
35 bool PrintInstantiation;
36
37 raw_ostream& Indent() { return Indent(Indentation); }
38 raw_ostream& Indent(unsigned Indentation);
39 void ProcessDeclGroup(SmallVectorImpl<Decl*>& Decls);
40
41 void Print(AccessSpecifier AS);
42 void PrintConstructorInitializers(CXXConstructorDecl *CDecl,
43 std::string &Proto);
44
45 /// Print an Objective-C method type in parentheses.
46 ///
47 /// \param Quals The Objective-C declaration qualifiers.
48 /// \param T The type to print.
49 void PrintObjCMethodType(ASTContext &Ctx, Decl::ObjCDeclQualifier Quals,
50 QualType T);
51
52 void PrintObjCTypeParams(ObjCTypeParamList *Params);
53 void PrintOpenACCRoutineOnLambda(Decl *D);
54
55 public:
56 DeclPrinter(raw_ostream &Out, const PrintingPolicy &Policy,
57 const ASTContext &Context, unsigned Indentation = 0,
58 bool PrintInstantiation = false)
59 : Out(Out), Policy(Policy), Context(Context), Indentation(Indentation),
60 PrintInstantiation(PrintInstantiation) {}
61
62 void VisitDeclContext(DeclContext *DC, bool Indent = true);
63
64 void VisitTranslationUnitDecl(TranslationUnitDecl *D);
65 void VisitTypedefDecl(TypedefDecl *D);
66 void VisitTypeAliasDecl(TypeAliasDecl *D);
67 void VisitEnumDecl(EnumDecl *D);
68 void VisitRecordDecl(RecordDecl *D);
69 void VisitEnumConstantDecl(EnumConstantDecl *D);
70 void VisitEmptyDecl(EmptyDecl *D);
71 void VisitFunctionDecl(FunctionDecl *D);
72 void VisitFriendDecl(FriendDecl *D);
73 void VisitFriendTemplateDecl(FriendTemplateDecl *D);
74 void VisitFieldDecl(FieldDecl *D);
75 void VisitVarDecl(VarDecl *D);
76 void VisitLabelDecl(LabelDecl *D);
77 void VisitParmVarDecl(ParmVarDecl *D);
78 void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
79 void VisitTopLevelStmtDecl(TopLevelStmtDecl *D);
80 void VisitImportDecl(ImportDecl *D);
81 void VisitStaticAssertDecl(StaticAssertDecl *D);
82 void VisitNamespaceDecl(NamespaceDecl *D);
83 void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
84 void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
85 void VisitCXXRecordDecl(CXXRecordDecl *D);
86 void VisitLinkageSpecDecl(LinkageSpecDecl *D);
87 void VisitTemplateDecl(const TemplateDecl *D);
88 void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
89 void VisitClassTemplateDecl(ClassTemplateDecl *D);
90 void VisitExplicitInstantiationDecl(ExplicitInstantiationDecl *D);
91 void VisitClassTemplateSpecializationDecl(
92 ClassTemplateSpecializationDecl *D);
93 void VisitClassTemplatePartialSpecializationDecl(
94 ClassTemplatePartialSpecializationDecl *D);
95 void VisitObjCMethodDecl(ObjCMethodDecl *D);
96 void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
97 void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
98 void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
99 void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
100 void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
101 void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
102 void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
103 void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
104 void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
105 void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
106 void VisitUsingDecl(UsingDecl *D);
107 void VisitUsingEnumDecl(UsingEnumDecl *D);
108 void VisitUsingShadowDecl(UsingShadowDecl *D);
109 void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
110 void VisitOMPAllocateDecl(OMPAllocateDecl *D);
111 void VisitOMPRequiresDecl(OMPRequiresDecl *D);
112 void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
113 void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D);
114 void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
115 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *TTP);
116 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *NTTP);
117 void VisitTemplateTemplateParmDecl(const TemplateTemplateParmDecl *);
118 void VisitHLSLBufferDecl(HLSLBufferDecl *D);
119 void VisitCXXExpansionStmtDecl(const CXXExpansionStmtDecl *D);
120
121 void VisitOpenACCDeclareDecl(OpenACCDeclareDecl *D);
122 void VisitOpenACCRoutineDecl(OpenACCRoutineDecl *D);
123
124 void printTemplateParameters(const TemplateParameterList *Params,
125 bool OmitTemplateKW = false);
126 void printTemplateArguments(ArrayRef<TemplateArgument> Args,
127 const TemplateParameterList *Params);
128 void printTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
129 const TemplateParameterList *Params);
130 enum class AttrPosAsWritten { Default = 0, Left, Right };
131 std::optional<std::string>
132 prettyPrintAttributes(const Decl *D,
133 AttrPosAsWritten Pos = AttrPosAsWritten::Default);
134
135 void prettyPrintPragmas(Decl *D);
136 void printDeclType(QualType T, StringRef DeclName, bool Pack = false);
137 };
138}
139
140void Decl::print(raw_ostream &Out, unsigned Indentation,
141 bool PrintInstantiation) const {
142 print(Out, getASTContext().getPrintingPolicy(), Indentation, PrintInstantiation);
143}
144
145void Decl::print(raw_ostream &Out, const PrintingPolicy &Policy,
146 unsigned Indentation, bool PrintInstantiation) const {
147 DeclPrinter Printer(Out, Policy, getASTContext(), Indentation,
148 PrintInstantiation);
149 Printer.Visit(const_cast<Decl*>(this));
150}
151
152void TemplateParameterList::print(raw_ostream &Out, const ASTContext &Context,
153 bool OmitTemplateKW) const {
154 print(Out, Context, Context.getPrintingPolicy(), OmitTemplateKW);
155}
156
157void TemplateParameterList::print(raw_ostream &Out, const ASTContext &Context,
158 const PrintingPolicy &Policy,
159 bool OmitTemplateKW) const {
160 DeclPrinter Printer(Out, Policy, Context);
161 Printer.printTemplateParameters(this, OmitTemplateKW);
162}
163
165 // FIXME: This should be on the Type class!
166 QualType BaseType = T;
167 while (!BaseType->isSpecifierType()) {
168 if (const PointerType *PTy = BaseType->getAs<PointerType>())
169 BaseType = PTy->getPointeeType();
170 else if (const ObjCObjectPointerType *OPT =
171 BaseType->getAs<ObjCObjectPointerType>())
172 BaseType = OPT->getPointeeType();
173 else if (const BlockPointerType *BPy = BaseType->getAs<BlockPointerType>())
174 BaseType = BPy->getPointeeType();
175 else if (const ArrayType *ATy = dyn_cast<ArrayType>(BaseType))
176 BaseType = ATy->getElementType();
177 else if (const FunctionType *FTy = BaseType->getAs<FunctionType>())
178 BaseType = FTy->getReturnType();
179 else if (const VectorType *VTy = BaseType->getAs<VectorType>())
180 BaseType = VTy->getElementType();
181 else if (const ReferenceType *RTy = BaseType->getAs<ReferenceType>())
182 BaseType = RTy->getPointeeType();
183 else if (const AutoType *ATy = BaseType->getAs<AutoType>())
184 BaseType = ATy->getDeducedType();
185 else if (const ParenType *PTy = BaseType->getAs<ParenType>())
186 BaseType = PTy->desugar();
187 else
188 // This must be a syntax error.
189 break;
190 }
191 return BaseType;
192}
193
195 if (TypedefNameDecl* TDD = dyn_cast<TypedefNameDecl>(D))
196 return TDD->getUnderlyingType();
197 if (ValueDecl* VD = dyn_cast<ValueDecl>(D))
198 return VD->getType();
199 return QualType();
200}
201
202void Decl::printGroup(Decl** Begin, unsigned NumDecls,
203 raw_ostream &Out, const PrintingPolicy &Policy,
204 unsigned Indentation) {
205 if (NumDecls == 1) {
206 (*Begin)->print(Out, Policy, Indentation);
207 return;
208 }
209
210 Decl** End = Begin + NumDecls;
211 if (isa<TagDecl>(*Begin))
212 ++Begin;
213
214 PrintingPolicy SubPolicy(Policy);
215
216 bool isFirst = true;
217 for ( ; Begin != End; ++Begin) {
218 if (isFirst) {
219 isFirst = false;
220 } else {
221 Out << ", ";
222 SubPolicy.SuppressSpecifiers = true;
223 }
224
225 (*Begin)->print(Out, SubPolicy, Indentation);
226 }
227}
228
229LLVM_DUMP_METHOD void DeclContext::dumpDeclContext() const {
230 // Get the translation unit
231 const DeclContext *DC = this;
232 while (!DC->isTranslationUnit())
233 DC = DC->getParent();
234
235 ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
236 DeclPrinter Printer(llvm::errs(), Ctx.getPrintingPolicy(), Ctx, 0);
237 Printer.VisitDeclContext(const_cast<DeclContext *>(this), /*Indent=*/false);
238}
239
240raw_ostream& DeclPrinter::Indent(unsigned Indentation) {
241 for (unsigned i = 0; i != Indentation; ++i)
242 Out << " ";
243 return Out;
244}
245
246static DeclPrinter::AttrPosAsWritten getPosAsWritten(const Attr *A,
247 const Decl *D) {
248 SourceLocation ALoc = A->getLoc();
249 SourceLocation DLoc = D->getLocation();
250 const ASTContext &C = D->getASTContext();
251 if (ALoc.isInvalid() || DLoc.isInvalid())
252 return DeclPrinter::AttrPosAsWritten::Left;
253
254 if (C.getSourceManager().isBeforeInTranslationUnit(ALoc, DLoc))
255 return DeclPrinter::AttrPosAsWritten::Left;
256
257 return DeclPrinter::AttrPosAsWritten::Right;
258}
259
260std::optional<std::string>
261DeclPrinter::prettyPrintAttributes(const Decl *D,
262 AttrPosAsWritten Pos /*=Default*/) {
263 if (Policy.SuppressDeclAttributes || !D->hasAttrs())
264 return std::nullopt;
265
266 std::string AttrStr;
267 llvm::raw_string_ostream AOut(AttrStr);
268 llvm::ListSeparator LS(" ");
269 for (auto *A : D->getAttrs()) {
270 if (A->isInherited() || A->isImplicit())
271 continue;
272 // Print out the keyword attributes, they aren't regular attributes.
273 if (Policy.PolishForDeclaration && !A->isKeywordAttribute())
274 continue;
275 switch (A->getKind()) {
276#define ATTR(X)
277#define PRAGMA_SPELLING_ATTR(X) case attr::X:
278#include "clang/Basic/AttrList.inc"
279 break;
280 default:
281 AttrPosAsWritten APos = getPosAsWritten(A, D);
282 assert(APos != AttrPosAsWritten::Default &&
283 "Default not a valid for an attribute location");
284 if (Pos == AttrPosAsWritten::Default || Pos == APos) {
285 AOut << LS;
286 A->printPretty(AOut, Policy);
287 }
288 break;
289 }
290 }
291 if (AttrStr.empty())
292 return std::nullopt;
293 return AttrStr;
294}
295
296void DeclPrinter::PrintOpenACCRoutineOnLambda(Decl *D) {
297 CXXRecordDecl *CXXRD = nullptr;
298 if (const auto *VD = dyn_cast<VarDecl>(D)) {
299 if (const auto *Init = VD->getInit())
300 CXXRD = Init->getType().isNull() ? nullptr
301 : Init->getType()->getAsCXXRecordDecl();
302 } else if (const auto *FD = dyn_cast<FieldDecl>(D)) {
303 CXXRD =
304 FD->getType().isNull() ? nullptr : FD->getType()->getAsCXXRecordDecl();
305 }
306
307 if (!CXXRD || !CXXRD->isLambda())
308 return;
309
310 if (const auto *Call = CXXRD->getLambdaCallOperator()) {
311 for (auto *A : Call->specific_attrs<OpenACCRoutineDeclAttr>()) {
312 A->printPretty(Out, Policy);
313 Indent();
314 }
315 }
316}
317
318void DeclPrinter::prettyPrintPragmas(Decl *D) {
319 if (Policy.PolishForDeclaration)
320 return;
321
322 PrintOpenACCRoutineOnLambda(D);
323
324 if (D->hasAttrs()) {
325 AttrVec &Attrs = D->getAttrs();
326 for (auto *A : Attrs) {
327 switch (A->getKind()) {
328#define ATTR(X)
329#define PRAGMA_SPELLING_ATTR(X) case attr::X:
330#include "clang/Basic/AttrList.inc"
331 A->printPretty(Out, Policy);
332 Indent();
333 break;
334 default:
335 break;
336 }
337 }
338 }
339}
340
341void DeclPrinter::printDeclType(QualType T, StringRef DeclName, bool Pack) {
342 // Normally, a PackExpansionType is written as T[3]... (for instance, as a
343 // template argument), but if it is the type of a declaration, the ellipsis
344 // is placed before the name being declared.
345 if (auto *PET = T->getAs<PackExpansionType>()) {
346 Pack = true;
347 T = PET->getPattern();
348 }
349 T.print(Out, Policy, (Pack ? "..." : "") + DeclName, Indentation);
350}
351
352void DeclPrinter::ProcessDeclGroup(SmallVectorImpl<Decl*>& Decls) {
353 this->Indent();
354 Decl::printGroup(Decls.data(), Decls.size(), Out, Policy, Indentation);
355 Out << ";\n";
356 Decls.clear();
357
358}
359
360void DeclPrinter::Print(AccessSpecifier AS) {
361 const auto AccessSpelling = getAccessSpelling(AS);
362 if (AccessSpelling.empty())
363 llvm_unreachable("No access specifier!");
364 Out << AccessSpelling;
365}
366
367void DeclPrinter::PrintConstructorInitializers(CXXConstructorDecl *CDecl,
368 std::string &Proto) {
369 bool HasInitializerList = false;
370 for (const auto *BMInitializer : CDecl->inits()) {
371 if (BMInitializer->isInClassMemberInitializer())
372 continue;
373 if (!BMInitializer->isWritten())
374 continue;
375
376 if (!HasInitializerList) {
377 Proto += " : ";
378 Out << Proto;
379 Proto.clear();
380 HasInitializerList = true;
381 } else
382 Out << ", ";
383
384 if (BMInitializer->isAnyMemberInitializer()) {
385 FieldDecl *FD = BMInitializer->getAnyMember();
386 Out << *FD;
387 } else if (BMInitializer->isDelegatingInitializer()) {
388 Out << CDecl->getNameAsString();
389 } else {
390 Out << QualType(BMInitializer->getBaseClass(), 0).getAsString(Policy);
391 }
392
393 if (Expr *Init = BMInitializer->getInit()) {
394 bool OutParens = !isa<InitListExpr>(Init);
395
396 if (OutParens)
397 Out << "(";
398
399 if (ExprWithCleanups *Tmp = dyn_cast<ExprWithCleanups>(Init))
400 Init = Tmp->getSubExpr();
401
402 Init = Init->IgnoreParens();
403
404 Expr *SimpleInit = nullptr;
405 Expr **Args = nullptr;
406 unsigned NumArgs = 0;
407 if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
408 Args = ParenList->getExprs();
409 NumArgs = ParenList->getNumExprs();
410 } else if (CXXConstructExpr *Construct =
411 dyn_cast<CXXConstructExpr>(Init)) {
412 Args = Construct->getArgs();
413 NumArgs = Construct->getNumArgs();
414 } else
415 SimpleInit = Init;
416
417 if (SimpleInit)
418 SimpleInit->printPretty(Out, nullptr, Policy, Indentation, "\n",
419 &Context);
420 else {
421 for (unsigned I = 0; I != NumArgs; ++I) {
422 assert(Args[I] != nullptr && "Expected non-null Expr");
423 if (isa<CXXDefaultArgExpr>(Args[I]))
424 break;
425
426 if (I)
427 Out << ", ";
428 Args[I]->printPretty(Out, nullptr, Policy, Indentation, "\n",
429 &Context);
430 }
431 }
432
433 if (OutParens)
434 Out << ")";
435 } else {
436 Out << "()";
437 }
438
439 if (BMInitializer->isPackExpansion())
440 Out << "...";
441 }
442}
443
444//----------------------------------------------------------------------------
445// Common C declarations
446//----------------------------------------------------------------------------
447
448void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
449 if (Policy.TerseOutput)
450 return;
451
452 if (Indent)
453 Indentation += Policy.Indentation;
454
456 for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
457 D != DEnd; ++D) {
458
459 // Don't print ObjCIvarDecls, as they are printed when visiting the
460 // containing ObjCInterfaceDecl.
461 if (isa<ObjCIvarDecl>(*D))
462 continue;
463
464 // Skip over implicit declarations in pretty-printing mode.
465 if (D->isImplicit())
466 continue;
467
468 // Don't print implicit specializations, as they are printed when visiting
469 // corresponding templates.
470 if (auto FD = dyn_cast<FunctionDecl>(*D))
471 if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation &&
473 continue;
474
475 // The next bits of code handle stuff like "struct {int x;} a,b"; we're
476 // forced to merge the declarations because there's no other way to
477 // refer to the struct in question. When that struct is named instead, we
478 // also need to merge to avoid splitting off a stand-alone struct
479 // declaration that produces the warning ext_no_declarators in some
480 // contexts.
481 //
482 // This limited merging is safe without a bunch of other checks because it
483 // only merges declarations directly referring to the tag, not typedefs.
484 //
485 // Check whether the current declaration should be grouped with a previous
486 // non-free-standing tag declaration.
487 QualType CurDeclType = getDeclType(*D);
488 if (!Decls.empty() && !CurDeclType.isNull()) {
489 QualType BaseType = GetBaseType(CurDeclType);
490 if (const auto *TT = dyn_cast_or_null<TagType>(BaseType);
491 TT && TT->isTagOwned()) {
492 if (TT->getDecl() == Decls[0]) {
493 Decls.push_back(*D);
494 continue;
495 }
496 }
497 }
498
499 // If we have a merged group waiting to be handled, handle it now.
500 if (!Decls.empty())
501 ProcessDeclGroup(Decls);
502
503 // If the current declaration is not a free standing declaration, save it
504 // so we can merge it with the subsequent declaration(s) using it.
505 if (isa<TagDecl>(*D) && !cast<TagDecl>(*D)->isFreeStanding()) {
506 Decls.push_back(*D);
507 continue;
508 }
509
510 if (isa<AccessSpecDecl>(*D)) {
511 Indentation -= Policy.Indentation;
512 this->Indent();
513 Print(D->getAccess());
514 Out << ":\n";
515 Indentation += Policy.Indentation;
516 continue;
517 }
518
519 this->Indent();
520 Visit(*D);
521
522 // FIXME: Need to be able to tell the DeclPrinter when
523 const char *Terminator = nullptr;
527 Terminator = nullptr;
529 Terminator = nullptr;
530 else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->hasBody())
531 Terminator = nullptr;
532 else if (auto FD = dyn_cast<FunctionDecl>(*D)) {
533 if (FD->doesThisDeclarationHaveABody() && !FD->isDefaulted())
534 Terminator = nullptr;
535 else
536 Terminator = ";";
537 } else if (auto TD = dyn_cast<FunctionTemplateDecl>(*D)) {
538 if (TD->getTemplatedDecl()->doesThisDeclarationHaveABody())
539 Terminator = nullptr;
540 else
541 Terminator = ";";
545 Terminator = nullptr;
546 else if (isa<EnumConstantDecl>(*D)) {
548 ++Next;
549 if (Next != DEnd)
550 Terminator = ",";
551 } else
552 Terminator = ";";
553
554 if (Terminator)
555 Out << Terminator;
556 if (!Policy.TerseOutput &&
557 ((isa<FunctionDecl>(*D) &&
558 cast<FunctionDecl>(*D)->doesThisDeclarationHaveABody()) ||
560 cast<FunctionTemplateDecl>(*D)->getTemplatedDecl()->doesThisDeclarationHaveABody())))
561 ; // StmtPrinter already added '\n' after CompoundStmt.
562 else
563 Out << "\n";
564
565 // Declare target attribute is special one, natural spelling for the pragma
566 // assumes "ending" construct so print it here.
567 if (D->hasAttr<OMPDeclareTargetDeclAttr>())
568 Out << "#pragma omp end declare target\n";
569 }
570
571 if (!Decls.empty())
572 ProcessDeclGroup(Decls);
573
574 if (Indent)
575 Indentation -= Policy.Indentation;
576}
577
578void DeclPrinter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
579 VisitDeclContext(D, false);
580}
581
582void DeclPrinter::VisitTypedefDecl(TypedefDecl *D) {
583 if (!Policy.SuppressSpecifiers) {
584 Out << "typedef ";
585
586 if (D->isModulePrivate())
587 Out << "__module_private__ ";
588 }
590 Ty.print(Out, Policy, D->getName(), Indentation);
591
592 if (std::optional<std::string> Attrs = prettyPrintAttributes(D))
593 Out << ' ' << *Attrs;
594}
595
596void DeclPrinter::VisitTypeAliasDecl(TypeAliasDecl *D) {
597 Out << "using " << *D;
598 if (std::optional<std::string> Attrs = prettyPrintAttributes(D))
599 Out << ' ' << *Attrs;
600 Out << " = " << D->getTypeSourceInfo()->getType().getAsString(Policy);
601}
602
603void DeclPrinter::VisitEnumDecl(EnumDecl *D) {
604 if (!Policy.SuppressSpecifiers && D->isModulePrivate())
605 Out << "__module_private__ ";
606 Out << "enum";
607 if (D->isScoped()) {
608 if (D->isScopedUsingClassTag())
609 Out << " class";
610 else
611 Out << " struct";
612 }
613
614 if (std::optional<std::string> Attrs = prettyPrintAttributes(D))
615 Out << ' ' << *Attrs;
616
617 if (D->getDeclName())
618 Out << ' ' << D->getDeclName();
619
620 if (D->isFixed())
621 Out << " : " << D->getIntegerType().stream(Policy);
622
623 if (D->isCompleteDefinition()) {
624 Out << " {\n";
625 VisitDeclContext(D);
626 Indent() << "}";
627 }
628}
629
630void DeclPrinter::VisitRecordDecl(RecordDecl *D) {
631 if (!Policy.SuppressSpecifiers && D->isModulePrivate())
632 Out << "__module_private__ ";
633 Out << D->getKindName();
634
635 if (std::optional<std::string> Attrs = prettyPrintAttributes(D))
636 Out << ' ' << *Attrs;
637
638 if (D->getIdentifier())
639 Out << ' ' << *D;
640
641 if (D->isCompleteDefinition()) {
642 Out << " {\n";
643 VisitDeclContext(D);
644 Indent() << "}";
645 }
646}
647
648void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) {
649 Out << *D;
650 if (std::optional<std::string> Attrs = prettyPrintAttributes(D))
651 Out << ' ' << *Attrs;
652 if (Expr *Init = D->getInitExpr()) {
653 Out << " = ";
654 Init->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
655 }
656}
657
658static void printExplicitSpecifier(ExplicitSpecifier ES, llvm::raw_ostream &Out,
659 PrintingPolicy &Policy, unsigned Indentation,
660 const ASTContext &Context) {
661 std::string Proto = "explicit";
662 llvm::raw_string_ostream EOut(Proto);
663 if (ES.getExpr()) {
664 EOut << "(";
665 ES.getExpr()->printPretty(EOut, nullptr, Policy, Indentation, "\n",
666 &Context);
667 EOut << ")";
668 }
669 EOut << " ";
670 Out << Proto;
671}
672
673void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
676 prettyPrintPragmas(D);
677 if (std::optional<std::string> Attrs =
678 prettyPrintAttributes(D, AttrPosAsWritten::Left))
679 Out << *Attrs << ' ';
680 }
681
683 Out << "template<> ";
684 else if (!D->getDescribedFunctionTemplate()) {
686 printTemplateParameters(TPL);
687 }
688
689 CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
690 CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
691 CXXDeductionGuideDecl *GuideDecl = dyn_cast<CXXDeductionGuideDecl>(D);
692 if (!Policy.SuppressSpecifiers) {
693 switch (D->getStorageClass()) {
694 case SC_None: break;
695 case SC_Extern: Out << "extern "; break;
696 case SC_Static: Out << "static "; break;
697 case SC_PrivateExtern: Out << "__private_extern__ "; break;
698 case SC_Auto: case SC_Register:
699 llvm_unreachable("invalid for functions");
700 }
701
702 if (D->isInlineSpecified()) Out << "inline ";
703 if (D->isVirtualAsWritten()) Out << "virtual ";
704 if (D->isModulePrivate()) Out << "__module_private__ ";
706 Out << "constexpr ";
707 if (D->isConsteval()) Out << "consteval ";
708 else if (D->isImmediateFunction())
709 Out << "immediate ";
711 if (ExplicitSpec.isSpecified())
712 printExplicitSpecifier(ExplicitSpec, Out, Policy, Indentation, Context);
713 }
714
715 PrintingPolicy SubPolicy(Policy);
716 SubPolicy.SuppressSpecifiers = false;
717 std::string Proto;
718
719 if (Policy.FullyQualifiedName) {
720 Proto += D->getQualifiedNameAsString();
721 } else {
722 llvm::raw_string_ostream OS(Proto);
723 if (!Policy.SuppressScope)
724 D->getQualifier().print(OS, Policy);
725 D->getNameInfo().printName(OS, Policy);
726 }
727
728 if (GuideDecl)
729 Proto = GuideDecl->getDeducedTemplate()->getDeclName().getAsString();
731 llvm::raw_string_ostream POut(Proto);
732 DeclPrinter TArgPrinter(POut, SubPolicy, Context, Indentation);
733 const auto *TArgAsWritten = D->getTemplateSpecializationArgsAsWritten();
734 if (TArgAsWritten && !Policy.PrintAsCanonical)
735 TArgPrinter.printTemplateArguments(TArgAsWritten->arguments(), nullptr);
736 else if (const TemplateArgumentList *TArgs =
738 TArgPrinter.printTemplateArguments(TArgs->asArray(), nullptr);
739 }
740
741 QualType Ty = D->getType();
742 while (const ParenType *PT = dyn_cast<ParenType>(Ty)) {
743 Proto = '(' + Proto + ')';
744 Ty = PT->getInnerType();
745 }
746
747 if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
748 const FunctionProtoType *FT = nullptr;
749 if (D->hasWrittenPrototype())
750 FT = dyn_cast<FunctionProtoType>(AFT);
751
752 Proto += "(";
753 if (FT) {
754 llvm::raw_string_ostream POut(Proto);
755 DeclPrinter ParamPrinter(POut, SubPolicy, Context, Indentation);
756 for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
757 if (i) POut << ", ";
758 ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
759 }
760
761 if (FT->isVariadic()) {
762 if (D->getNumParams()) POut << ", ";
763 POut << "...";
764 } else if (!D->getNumParams() && !Context.getLangOpts().CPlusPlus) {
765 // The function has a prototype, so it needs to retain the prototype
766 // in C.
767 POut << "void";
768 }
769 } else if (D->doesThisDeclarationHaveABody() && !D->hasPrototype()) {
770 for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
771 if (i)
772 Proto += ", ";
773 Proto += D->getParamDecl(i)->getNameAsString();
774 }
775 }
776
777 Proto += ")";
778
779 if (FT) {
780 if (FT->isConst())
781 Proto += " const";
782 if (FT->isVolatile())
783 Proto += " volatile";
784 if (FT->isRestrict())
785 Proto += " restrict";
786
787 switch (FT->getRefQualifier()) {
788 case RQ_None:
789 break;
790 case RQ_LValue:
791 Proto += " &";
792 break;
793 case RQ_RValue:
794 Proto += " &&";
795 break;
796 }
797 }
798
799 if (FT && FT->hasDynamicExceptionSpec()) {
800 Proto += " throw(";
801 if (FT->getExceptionSpecType() == EST_MSAny)
802 Proto += "...";
803 else
804 for (unsigned I = 0, N = FT->getNumExceptions(); I != N; ++I) {
805 if (I)
806 Proto += ", ";
807
808 Proto += FT->getExceptionType(I).getAsString(SubPolicy);
809 }
810 Proto += ")";
811 } else if (FT && isNoexceptExceptionSpec(FT->getExceptionSpecType())) {
812 Proto += " noexcept";
814 Proto += "(";
815 llvm::raw_string_ostream EOut(Proto);
816 FT->getNoexceptExpr()->printPretty(EOut, nullptr, SubPolicy,
817 Indentation, "\n", &Context);
818 Proto += ")";
819 }
820 }
821
822 if (CDecl) {
823 if (!Policy.TerseOutput)
824 PrintConstructorInitializers(CDecl, Proto);
825 } else if (!ConversionDecl && !isa<CXXDestructorDecl>(D)) {
826 if (FT && FT->hasTrailingReturn()) {
827 if (!GuideDecl)
828 Out << "auto ";
829 Out << Proto << " -> ";
830 Proto.clear();
831 }
832 AFT->getReturnType().print(Out, Policy, Proto);
833 Proto.clear();
834 }
835 Out << Proto;
836
837 if (const AssociatedConstraint &TrailingRequiresClause =
839 Out << " requires ";
840 // FIXME: The printer could support printing expressions and types as if
841 // expanded by an index. Pass in the ArgumentPackSubstitutionIndex when
842 // that's supported.
843 TrailingRequiresClause.ConstraintExpr->printPretty(
844 Out, nullptr, SubPolicy, Indentation, "\n", &Context);
845 }
846 } else {
847 Ty.print(Out, Policy, Proto);
848 }
849
850 if (std::optional<std::string> Attrs =
851 prettyPrintAttributes(D, AttrPosAsWritten::Right))
852 Out << ' ' << *Attrs;
853
854 if (D->isPureVirtual())
855 Out << " = 0";
856 else if (D->isDeletedAsWritten()) {
857 Out << " = delete";
858 if (const StringLiteral *M = D->getDeletedMessage()) {
859 Out << "(";
860 M->outputString(Out);
861 Out << ")";
862 }
863 } else if (D->isExplicitlyDefaulted())
864 Out << " = default";
865 else if (D->doesThisDeclarationHaveABody()) {
866 if (!Policy.TerseOutput) {
867 if (!D->hasPrototype() && D->getNumParams()) {
868 // This is a K&R function definition, so we need to print the
869 // parameters.
870 Out << '\n';
871 DeclPrinter ParamPrinter(Out, SubPolicy, Context, Indentation);
872 Indentation += Policy.Indentation;
873 for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
874 Indent();
875 ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
876 Out << ";\n";
877 }
878 Indentation -= Policy.Indentation;
879 }
880
881 if (D->getBody())
882 D->getBody()->printPrettyControlled(Out, nullptr, SubPolicy, Indentation, "\n",
883 &Context);
884 } else {
885 if (!Policy.TerseOutput && isa<CXXConstructorDecl>(*D))
886 Out << " {}";
887 }
888 }
889}
890
891void DeclPrinter::VisitFriendDecl(FriendDecl *D) {
892 if (TypeSourceInfo *TSI = D->getFriendType()) {
893 Out << "friend ";
894 Out << TSI->getType().getAsString(Policy);
895 } else if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D->getFriendDecl())) {
896 Out << "friend ";
897 VisitFunctionDecl(FD);
898 } else if (FunctionTemplateDecl *FTD =
899 dyn_cast<FunctionTemplateDecl>(D->getFriendDecl())) {
900 Out << "friend ";
901 VisitFunctionTemplateDecl(FTD);
902 } else if (ClassTemplateDecl *CTD =
903 dyn_cast<ClassTemplateDecl>(D->getFriendDecl())) {
904 Out << "friend ";
905 VisitRedeclarableTemplateDecl(CTD);
906 }
907
908 if (D->isPackExpansion())
909 Out << "...";
910}
911
912void DeclPrinter::VisitFriendTemplateDecl(FriendTemplateDecl *D) {
914 printTemplateParameters(TPL);
915
917 if (D->getFriendType() || TN.isNull()) {
918 VisitFriendDecl(D);
919 } else {
920 Out << "friend ";
921 if (auto *CTD =
922 dyn_cast_if_present<ClassTemplateDecl>(TN.getAsTemplateDecl()))
923 Out << CTD->getTemplatedDecl()->getKindName() << ' ';
924 TN.print(Out, Policy,
927
928 if (D->isPackExpansion())
929 Out << "...";
930 }
931}
932
933void DeclPrinter::VisitFieldDecl(FieldDecl *D) {
934 prettyPrintPragmas(D);
935 // FIXME: add printing of pragma attributes if required.
936 if (!Policy.SuppressSpecifiers && D->isMutable())
937 Out << "mutable ";
938 if (!Policy.SuppressSpecifiers && D->isModulePrivate())
939 Out << "__module_private__ ";
940
942 stream(Policy, D->getName(), Indentation);
943
944 if (D->isBitField()) {
945 Out << " : ";
946 D->getBitWidth()->printPretty(Out, nullptr, Policy, Indentation, "\n",
947 &Context);
948 }
949
951 if (!Policy.SuppressInitializers && Init) {
953 Out << " ";
954 else
955 Out << " = ";
956 Init->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
957 }
958 if (std::optional<std::string> Attrs = prettyPrintAttributes(D))
959 Out << ' ' << *Attrs;
960}
961
962void DeclPrinter::VisitLabelDecl(LabelDecl *D) {
963 Out << *D << ":";
964}
965
966void DeclPrinter::VisitVarDecl(VarDecl *D) {
967 prettyPrintPragmas(D);
968
969 if (std::optional<std::string> Attrs =
970 prettyPrintAttributes(D, AttrPosAsWritten::Left))
971 Out << *Attrs << ' ';
972
973 if (const auto *Param = dyn_cast<ParmVarDecl>(D);
974 Param && Param->isExplicitObjectParameter())
975 Out << "this ";
976
978 ? D->getTypeSourceInfo()->getType()
980
981 if (!Policy.SuppressSpecifiers) {
983 if (SC != SC_None)
985
986 switch (D->getTSCSpec()) {
987 case TSCS_unspecified:
988 break;
989 case TSCS___thread:
990 Out << "__thread ";
991 break;
993 Out << "_Thread_local ";
994 break;
996 Out << "thread_local ";
997 break;
998 }
999
1000 if (D->isModulePrivate())
1001 Out << "__module_private__ ";
1002
1003 if (D->isConstexpr()) {
1004 Out << "constexpr ";
1005 T.removeLocalConst();
1006 }
1007 }
1008
1009 printDeclType(T, (isa<ParmVarDecl>(D) && Policy.CleanUglifiedParameters &&
1010 D->getIdentifier())
1012 : D->getName());
1013
1014 if (std::optional<std::string> Attrs =
1015 prettyPrintAttributes(D, AttrPosAsWritten::Right))
1016 Out << ' ' << *Attrs;
1017
1018 Expr *Init = D->getInit();
1019 if (!Policy.SuppressInitializers && Init) {
1020 bool ImplicitInit = false;
1021 if (D->isCXXForRangeDecl()) {
1022 // FIXME: We should print the range expression instead.
1023 ImplicitInit = true;
1024 } else if (CXXConstructExpr *Construct =
1025 dyn_cast<CXXConstructExpr>(Init->IgnoreImplicit())) {
1026 if (D->getInitStyle() == VarDecl::CallInit &&
1027 !Construct->isListInitialization()) {
1028 ImplicitInit = Construct->getNumArgs() == 0 ||
1029 Construct->getArg(0)->isDefaultArgument();
1030 }
1031 }
1032 if (!ImplicitInit) {
1034 Out << "(";
1035 else if (D->getInitStyle() == VarDecl::CInit) {
1036 Out << " = ";
1037 }
1038 PrintingPolicy SubPolicy(Policy);
1039 SubPolicy.SuppressSpecifiers = false;
1040 Init->printPretty(Out, nullptr, SubPolicy, Indentation, "\n", &Context);
1042 Out << ")";
1043 }
1044 }
1045}
1046
1047void DeclPrinter::VisitParmVarDecl(ParmVarDecl *D) {
1048 VisitVarDecl(D);
1049}
1050
1051void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
1052 Out << "__asm (";
1053 D->getAsmStringExpr()->printPretty(Out, nullptr, Policy, Indentation, "\n",
1054 &Context);
1055 Out << ")";
1056}
1057
1058void DeclPrinter::VisitTopLevelStmtDecl(TopLevelStmtDecl *D) {
1059 assert(D->getStmt());
1060 D->getStmt()->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
1061}
1062
1063void DeclPrinter::VisitImportDecl(ImportDecl *D) {
1064 Out << "@import " << D->getImportedModule()->getFullModuleName()
1065 << ";\n";
1066}
1067
1068void DeclPrinter::VisitStaticAssertDecl(StaticAssertDecl *D) {
1069 Out << "static_assert(";
1070 D->getAssertExpr()->printPretty(Out, nullptr, Policy, Indentation, "\n",
1071 &Context);
1072 if (Expr *E = D->getMessage()) {
1073 Out << ", ";
1074 E->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
1075 }
1076 Out << ")";
1077}
1078
1079//----------------------------------------------------------------------------
1080// C++ declarations
1081//----------------------------------------------------------------------------
1082void DeclPrinter::VisitNamespaceDecl(NamespaceDecl *D) {
1083 if (D->isInline())
1084 Out << "inline ";
1085
1086 Out << "namespace ";
1087 if (D->getDeclName())
1088 Out << D->getDeclName() << ' ';
1089 Out << "{\n";
1090
1091 VisitDeclContext(D);
1092 Indent() << "}";
1093}
1094
1095void DeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1096 Out << "using namespace ";
1097 D->getQualifier().print(Out, Policy);
1099}
1100
1101void DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1102 Out << "namespace " << *D << " = ";
1103 D->getQualifier().print(Out, Policy);
1104 Out << *D->getAliasedNamespace();
1105}
1106
1107void DeclPrinter::VisitEmptyDecl(EmptyDecl *D) {
1108 if (std::optional<std::string> Attrs = prettyPrintAttributes(D))
1109 Out << *Attrs;
1110}
1111
1112void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
1113 // FIXME: add printing of pragma attributes if required.
1114 if (!Policy.SuppressSpecifiers && D->isModulePrivate())
1115 Out << "__module_private__ ";
1116
1117 Out << D->getKindName() << ' ';
1118
1119 if (std::optional<std::string> Attrs =
1120 prettyPrintAttributes(D, AttrPosAsWritten::Left))
1121 Out << *Attrs << ' ';
1122
1123 if (D->getIdentifier()) {
1124 D->getQualifier().print(Out, Policy);
1125 Out << *D;
1126
1127 if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1128 const TemplateParameterList *TParams =
1129 S->getSpecializedTemplate()->getTemplateParameters();
1130 const ASTTemplateArgumentListInfo *TArgAsWritten =
1131 S->getTemplateArgsAsWritten();
1132 if (TArgAsWritten && !Policy.PrintAsCanonical)
1133 printTemplateArguments(TArgAsWritten->arguments(), TParams);
1134 else
1135 printTemplateArguments(S->getTemplateArgs().asArray(), TParams);
1136 }
1137 }
1138
1139 if (std::optional<std::string> Attrs =
1140 prettyPrintAttributes(D, AttrPosAsWritten::Right))
1141 Out << ' ' << *Attrs;
1142
1143 if (D->isCompleteDefinition()) {
1144 Out << ' ';
1145 // Print the base classes
1146 if (D->getNumBases()) {
1147 Out << ": ";
1148 for (CXXRecordDecl::base_class_iterator Base = D->bases_begin(),
1149 BaseEnd = D->bases_end(); Base != BaseEnd; ++Base) {
1150 if (Base != D->bases_begin())
1151 Out << ", ";
1152
1153 if (Base->isVirtual())
1154 Out << "virtual ";
1155
1156 AccessSpecifier AS = Base->getAccessSpecifierAsWritten();
1157 if (AS != AS_none) {
1158 Print(AS);
1159 Out << " ";
1160 }
1161 Out << Base->getType().getAsString(Policy);
1162
1163 if (Base->isPackExpansion())
1164 Out << "...";
1165 }
1166 Out << ' ';
1167 }
1168
1169 // Print the class definition
1170 // FIXME: Doesn't print access specifiers, e.g., "public:"
1171 if (Policy.TerseOutput) {
1172 Out << "{}";
1173 } else {
1174 Out << "{\n";
1175 VisitDeclContext(D);
1176 Indent() << "}";
1177 }
1178 }
1179}
1180
1181void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1182 const char *l;
1184 l = "C";
1185 else {
1187 "unknown language in linkage specification");
1188 l = "C++";
1189 }
1190
1191 Out << "extern \"" << l << "\" ";
1192 if (D->hasBraces()) {
1193 Out << "{\n";
1194 VisitDeclContext(D);
1195 Indent() << "}";
1196 } else
1197 Visit(*D->decls_begin());
1198}
1199
1200void DeclPrinter::printTemplateParameters(const TemplateParameterList *Params,
1201 bool OmitTemplateKW) {
1202 assert(Params);
1203
1204 // Don't print invented template parameter lists.
1205 if (!Params->empty() && Params->getParam(0)->isImplicit())
1206 return;
1207
1208 if (!OmitTemplateKW)
1209 Out << "template ";
1210 Out << '<';
1211
1212 bool NeedComma = false;
1213 for (const Decl *Param : *Params) {
1214 if (Param->isImplicit())
1215 continue;
1216
1217 if (NeedComma)
1218 Out << ", ";
1219 else
1220 NeedComma = true;
1221
1222 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
1223 VisitTemplateTypeParmDecl(TTP);
1224 } else if (auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
1225 VisitNonTypeTemplateParmDecl(NTTP);
1226 } else if (auto TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
1227 VisitTemplateTemplateParmDecl(TTPD);
1228 }
1229 }
1230
1231 Out << '>';
1232
1233 if (const Expr *RequiresClause = Params->getRequiresClause()) {
1234 Out << " requires ";
1235 RequiresClause->printPretty(Out, nullptr, Policy, Indentation, "\n",
1236 &Context);
1237 }
1238
1239 if (!OmitTemplateKW)
1240 Out << ' ';
1241}
1242
1243void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgument> Args,
1244 const TemplateParameterList *Params) {
1245 Out << "<";
1246 for (size_t I = 0, E = Args.size(); I < E; ++I) {
1247 if (I)
1248 Out << ", ";
1249 if (!Params)
1250 Args[I].print(Policy, Out, /*IncludeType*/ true);
1251 else
1252 Args[I].print(Policy, Out,
1254 Policy, Params, I));
1255 }
1256 Out << ">";
1257}
1258
1259void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
1260 const TemplateParameterList *Params) {
1261 Out << "<";
1262 for (size_t I = 0, E = Args.size(); I < E; ++I) {
1263 if (I)
1264 Out << ", ";
1265 if (!Params)
1266 Args[I].getArgument().print(Policy, Out, /*IncludeType*/ true);
1267 else
1268 Args[I].getArgument().print(
1269 Policy, Out,
1271 I));
1272 }
1273 Out << ">";
1274}
1275
1276void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
1277 printTemplateParameters(D->getTemplateParameters());
1278
1279 if (const TemplateTemplateParmDecl *TTP =
1280 dyn_cast<TemplateTemplateParmDecl>(D)) {
1281 switch (TTP->templateParameterKind()) {
1283 Out << "concept";
1284 break;
1286 Out << "auto";
1287 break;
1288 default:
1289 if (TTP->wasDeclaredWithTypename())
1290 Out << "typename";
1291 else
1292 Out << "class";
1293 break;
1294 }
1295
1296 if (TTP->isParameterPack())
1297 Out << " ...";
1298 else if (TTP->getDeclName())
1299 Out << ' ';
1300
1301 if (TTP->getDeclName()) {
1302 if (Policy.CleanUglifiedParameters && TTP->getIdentifier())
1303 Out << TTP->getIdentifier()->deuglifiedName();
1304 else
1305 Out << TTP->getDeclName();
1306 }
1307 } else if (auto *TD = D->getTemplatedDecl())
1308 Visit(TD);
1309 else if (const auto *Concept = dyn_cast<ConceptDecl>(D)) {
1310 Out << "concept " << Concept->getName() << " = " ;
1311 Concept->getConstraintExpr()->printPretty(Out, nullptr, Policy, Indentation,
1312 "\n", &Context);
1313 }
1314}
1315
1316void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
1317 prettyPrintPragmas(D->getTemplatedDecl());
1318 // Print any leading template parameter lists.
1319 if (const FunctionDecl *FD = D->getTemplatedDecl())
1321 printTemplateParameters(TPL);
1322 VisitRedeclarableTemplateDecl(D);
1323 // Declare target attribute is special one, natural spelling for the pragma
1324 // assumes "ending" construct so print it here.
1325 if (D->getTemplatedDecl()->hasAttr<OMPDeclareTargetDeclAttr>())
1326 Out << "#pragma omp end declare target\n";
1327
1328 // Never print "instantiations" for deduction guides (they don't really
1329 // have them).
1330 if (PrintInstantiation &&
1332 FunctionDecl *PrevDecl = D->getTemplatedDecl();
1333 const FunctionDecl *Def;
1334 if (PrevDecl->isDefined(Def) && Def != PrevDecl)
1335 return;
1336 for (auto *I : D->specializations())
1337 if (I->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) {
1338 if (!PrevDecl->isThisDeclarationADefinition())
1339 Out << ";\n";
1340 Indent();
1341 prettyPrintPragmas(I);
1342 Visit(I);
1343 }
1344 }
1345}
1346
1347void DeclPrinter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
1348 VisitRedeclarableTemplateDecl(D);
1349
1350 if (PrintInstantiation) {
1351 for (auto *I : D->specializations())
1352 if (I->getSpecializationKind() == TSK_ImplicitInstantiation) {
1354 Out << ";";
1355 Out << "\n";
1356 Indent();
1357 Visit(I);
1358 }
1359 }
1360}
1361
1362void DeclPrinter::VisitExplicitInstantiationDecl(ExplicitInstantiationDecl *D) {
1363 if (D->isExternTemplate())
1364 Out << "extern ";
1365 Out << "template ";
1366
1367 NamedDecl *Spec = D->getSpecialization();
1368
1369 // Build the qualified name with template arguments.
1370 std::string Name;
1371 llvm::raw_string_ostream NameOS(Name);
1372 if (D->getQualifierLoc())
1373 D->getQualifierLoc().getNestedNameSpecifier().print(NameOS, Policy);
1374 Spec->printName(NameOS, Policy);
1375 if (auto NumArgs = D->getNumTemplateArgs(); NumArgs && *NumArgs > 0) {
1377 for (unsigned I = 0; I < *NumArgs; ++I)
1378 Args.push_back(D->getTemplateArg(I));
1379 printTemplateArgumentList(NameOS, Args, Policy);
1380 }
1381
1382 if (auto *RD = dyn_cast<RecordDecl>(Spec)) {
1383 Out << RD->getKindName() << " " << Name;
1384 } else if (auto *FD = dyn_cast<FunctionDecl>(Spec)) {
1385 FD->getReturnType().print(Out, Policy);
1386 Out << " " << Name << "(";
1387 llvm::ListSeparator LS;
1388 for (const ParmVarDecl *P : FD->parameters()) {
1389 Out << LS;
1390 P->print(Out, Policy);
1391 }
1392 if (FD->isVariadic()) {
1393 Out << LS;
1394 Out << "...";
1395 }
1396 Out << ")";
1397 } else if (auto *TSI = D->getTypeAsWritten()) {
1398 TSI->getType().print(Out, Policy, Name);
1399 } else {
1400 llvm_unreachable("unexpected specialization kind");
1401 }
1402}
1403
1404void DeclPrinter::VisitClassTemplateSpecializationDecl(
1406 Out << "template<> ";
1407 VisitCXXRecordDecl(D);
1408}
1409
1410void DeclPrinter::VisitClassTemplatePartialSpecializationDecl(
1412 printTemplateParameters(D->getTemplateParameters());
1413 VisitCXXRecordDecl(D);
1414}
1415
1416void DeclPrinter::VisitCXXExpansionStmtDecl(const CXXExpansionStmtDecl *D) {
1417 D->getExpansionPattern()->printPretty(Out, /*PrinterHelper=*/nullptr, Policy,
1418 Indentation, "\n", &Context);
1419}
1420
1421//----------------------------------------------------------------------------
1422// Objective-C declarations
1423//----------------------------------------------------------------------------
1424
1425void DeclPrinter::PrintObjCMethodType(ASTContext &Ctx,
1427 QualType T) {
1428 Out << '(';
1430 Out << "in ";
1432 Out << "inout ";
1434 Out << "out ";
1436 Out << "bycopy ";
1438 Out << "byref ";
1440 Out << "oneway ";
1442 if (auto nullability = AttributedType::stripOuterNullability(T))
1443 Out << getNullabilitySpelling(*nullability, true) << ' ';
1444 }
1445
1447 Out << ')';
1448}
1449
1450void DeclPrinter::PrintObjCTypeParams(ObjCTypeParamList *Params) {
1451 Out << "<";
1452 unsigned First = true;
1453 for (auto *Param : *Params) {
1454 if (First) {
1455 First = false;
1456 } else {
1457 Out << ", ";
1458 }
1459
1460 switch (Param->getVariance()) {
1462 break;
1463
1465 Out << "__covariant ";
1466 break;
1467
1469 Out << "__contravariant ";
1470 break;
1471 }
1472
1473 Out << Param->getDeclName();
1474
1475 if (Param->hasExplicitBound()) {
1476 Out << " : " << Param->getUnderlyingType().getAsString(Policy);
1477 }
1478 }
1479 Out << ">";
1480}
1481
1482void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) {
1483 if (OMD->isInstanceMethod())
1484 Out << "- ";
1485 else
1486 Out << "+ ";
1487 if (!OMD->getReturnType().isNull()) {
1488 PrintObjCMethodType(OMD->getASTContext(), OMD->getObjCDeclQualifier(),
1489 OMD->getReturnType());
1490 }
1491
1492 std::string name = OMD->getSelector().getAsString();
1493 std::string::size_type pos, lastPos = 0;
1494 for (const auto *PI : OMD->parameters()) {
1495 // FIXME: selector is missing here!
1496 pos = name.find_first_of(':', lastPos);
1497 if (lastPos != 0)
1498 Out << " ";
1499 Out << name.substr(lastPos, pos - lastPos) << ':';
1500 PrintObjCMethodType(OMD->getASTContext(),
1501 PI->getObjCDeclQualifier(),
1502 PI->getType());
1503 Out << *PI;
1504 lastPos = pos + 1;
1505 }
1506
1507 if (OMD->parameters().empty())
1508 Out << name;
1509
1510 if (OMD->isVariadic())
1511 Out << ", ...";
1512
1513 if (std::optional<std::string> Attrs = prettyPrintAttributes(OMD))
1514 Out << ' ' << *Attrs;
1515
1516 if (OMD->getBody() && !Policy.TerseOutput) {
1517 Out << ' ';
1518 OMD->getBody()->printPretty(Out, nullptr, Policy, Indentation, "\n",
1519 &Context);
1520 }
1521 else if (Policy.PolishForDeclaration)
1522 Out << ';';
1523}
1524
1525void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) {
1526 std::string I = OID->getNameAsString();
1527 ObjCInterfaceDecl *SID = OID->getSuperClass();
1528
1529 bool eolnOut = false;
1530 if (SID)
1531 Out << "@implementation " << I << " : " << *SID;
1532 else
1533 Out << "@implementation " << I;
1534
1535 if (OID->ivar_size() > 0) {
1536 Out << "{\n";
1537 eolnOut = true;
1538 Indentation += Policy.Indentation;
1539 for (const auto *I : OID->ivars()) {
1540 Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
1541 getAsString(Policy) << ' ' << *I << ";\n";
1542 }
1543 Indentation -= Policy.Indentation;
1544 Out << "}\n";
1545 } else if (SID || !OID->decls().empty()) {
1546 Out << "\n";
1547 eolnOut = true;
1548 }
1549 VisitDeclContext(OID, false);
1550 if (!eolnOut)
1551 Out << "\n";
1552 Out << "@end";
1553}
1554
1555void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
1556 std::string I = OID->getNameAsString();
1557 ObjCInterfaceDecl *SID = OID->getSuperClass();
1558
1559 if (!OID->isThisDeclarationADefinition()) {
1560 Out << "@class " << I;
1561
1562 if (auto TypeParams = OID->getTypeParamListAsWritten()) {
1563 PrintObjCTypeParams(TypeParams);
1564 }
1565
1566 Out << ";";
1567 return;
1568 }
1569 bool eolnOut = false;
1570 if (std::optional<std::string> Attrs = prettyPrintAttributes(OID))
1571 Out << *Attrs << "\n";
1572
1573 Out << "@interface " << I;
1574
1575 if (auto TypeParams = OID->getTypeParamListAsWritten()) {
1576 PrintObjCTypeParams(TypeParams);
1577 }
1578
1579 if (SID)
1580 Out << " : " << QualType(OID->getSuperClassType(), 0).getAsString(Policy);
1581
1582 // Protocols?
1583 const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();
1584 if (!Protocols.empty()) {
1585 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
1586 E = Protocols.end(); I != E; ++I)
1587 Out << (I == Protocols.begin() ? '<' : ',') << **I;
1588 Out << "> ";
1589 }
1590
1591 if (OID->ivar_size() > 0) {
1592 Out << "{\n";
1593 eolnOut = true;
1594 Indentation += Policy.Indentation;
1595 for (const auto *I : OID->ivars()) {
1596 Indent() << I->getASTContext()
1597 .getUnqualifiedObjCPointerType(I->getType())
1598 .getAsString(Policy) << ' ' << *I << ";\n";
1599 }
1600 Indentation -= Policy.Indentation;
1601 Out << "}\n";
1602 } else if (SID || !OID->decls().empty()) {
1603 Out << "\n";
1604 eolnOut = true;
1605 }
1606
1607 VisitDeclContext(OID, false);
1608 if (!eolnOut)
1609 Out << "\n";
1610 Out << "@end";
1611 // FIXME: implement the rest...
1612}
1613
1614void DeclPrinter::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1615 if (!PID->isThisDeclarationADefinition()) {
1616 Out << "@protocol " << *PID << ";\n";
1617 return;
1618 }
1619 // Protocols?
1620 const ObjCList<ObjCProtocolDecl> &Protocols = PID->getReferencedProtocols();
1621 if (!Protocols.empty()) {
1622 Out << "@protocol " << *PID;
1623 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
1624 E = Protocols.end(); I != E; ++I)
1625 Out << (I == Protocols.begin() ? '<' : ',') << **I;
1626 Out << ">\n";
1627 } else
1628 Out << "@protocol " << *PID << '\n';
1629 VisitDeclContext(PID, false);
1630 Out << "@end";
1631}
1632
1633void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) {
1634 Out << "@implementation ";
1635 if (const auto *CID = PID->getClassInterface())
1636 Out << *CID;
1637 else
1638 Out << "<<error-type>>";
1639 Out << '(' << *PID << ")\n";
1640
1641 VisitDeclContext(PID, false);
1642 Out << "@end";
1643 // FIXME: implement the rest...
1644}
1645
1646void DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) {
1647 Out << "@interface ";
1648 if (const auto *CID = PID->getClassInterface())
1649 Out << *CID;
1650 else
1651 Out << "<<error-type>>";
1652 if (auto TypeParams = PID->getTypeParamList()) {
1653 PrintObjCTypeParams(TypeParams);
1654 }
1655 Out << "(" << *PID << ")\n";
1656 if (PID->ivar_size() > 0) {
1657 Out << "{\n";
1658 Indentation += Policy.Indentation;
1659 for (const auto *I : PID->ivars())
1660 Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
1661 getAsString(Policy) << ' ' << *I << ";\n";
1662 Indentation -= Policy.Indentation;
1663 Out << "}\n";
1664 }
1665
1666 VisitDeclContext(PID, false);
1667 Out << "@end";
1668
1669 // FIXME: implement the rest...
1670}
1671
1672void DeclPrinter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID) {
1673 Out << "@compatibility_alias " << *AID
1674 << ' ' << *AID->getClassInterface() << ";\n";
1675}
1676
1677/// PrintObjCPropertyDecl - print a property declaration.
1678///
1679/// Print attributes in the following order:
1680/// - class
1681/// - nonatomic | atomic
1682/// - assign | retain | strong | copy | weak | unsafe_unretained
1683/// - readwrite | readonly
1684/// - getter & setter
1685/// - nullability
1686void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
1688 Out << "@required\n";
1690 Out << "@optional\n";
1691
1692 QualType T = PDecl->getType();
1693
1694 Out << "@property";
1696 bool first = true;
1697 Out << "(";
1699 Out << (first ? "" : ", ") << "class";
1700 first = false;
1701 }
1702
1704 Out << (first ? "" : ", ") << "direct";
1705 first = false;
1706 }
1707
1708 if (PDecl->getPropertyAttributes() &
1710 Out << (first ? "" : ", ") << "nonatomic";
1711 first = false;
1712 }
1714 Out << (first ? "" : ", ") << "atomic";
1715 first = false;
1716 }
1717
1719 Out << (first ? "" : ", ") << "assign";
1720 first = false;
1721 }
1723 Out << (first ? "" : ", ") << "retain";
1724 first = false;
1725 }
1726
1728 Out << (first ? "" : ", ") << "strong";
1729 first = false;
1730 }
1732 Out << (first ? "" : ", ") << "copy";
1733 first = false;
1734 }
1736 Out << (first ? "" : ", ") << "weak";
1737 first = false;
1738 }
1739 if (PDecl->getPropertyAttributes() &
1741 Out << (first ? "" : ", ") << "unsafe_unretained";
1742 first = false;
1743 }
1744
1745 if (PDecl->getPropertyAttributes() &
1747 Out << (first ? "" : ", ") << "readwrite";
1748 first = false;
1749 }
1751 Out << (first ? "" : ", ") << "readonly";
1752 first = false;
1753 }
1754
1756 Out << (first ? "" : ", ") << "getter = ";
1757 PDecl->getGetterName().print(Out);
1758 first = false;
1759 }
1761 Out << (first ? "" : ", ") << "setter = ";
1762 PDecl->getSetterName().print(Out);
1763 first = false;
1764 }
1765
1766 if (PDecl->getPropertyAttributes() &
1768 if (auto nullability = AttributedType::stripOuterNullability(T)) {
1769 if (*nullability == NullabilityKind::Unspecified &&
1770 (PDecl->getPropertyAttributes() &
1772 Out << (first ? "" : ", ") << "null_resettable";
1773 } else {
1774 Out << (first ? "" : ", ")
1775 << getNullabilitySpelling(*nullability, true);
1776 }
1777 first = false;
1778 }
1779 }
1780
1781 (void) first; // Silence dead store warning due to idiomatic code.
1782 Out << ")";
1783 }
1784 std::string TypeStr = PDecl->getASTContext().getUnqualifiedObjCPointerType(T).
1785 getAsString(Policy);
1786 Out << ' ' << TypeStr;
1787 if (!StringRef(TypeStr).ends_with("*"))
1788 Out << ' ';
1789 Out << *PDecl;
1790 if (Policy.PolishForDeclaration)
1791 Out << ';';
1792}
1793
1794void DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) {
1796 Out << "@synthesize ";
1797 else
1798 Out << "@dynamic ";
1799 Out << *PID->getPropertyDecl();
1800 if (PID->getPropertyIvarDecl())
1801 Out << '=' << *PID->getPropertyIvarDecl();
1802}
1803
1804void DeclPrinter::VisitUsingDecl(UsingDecl *D) {
1805 if (!D->isAccessDeclaration())
1806 Out << "using ";
1807 if (D->hasTypename())
1808 Out << "typename ";
1809 D->getQualifier().print(Out, Policy);
1810
1811 // Use the correct record name when the using declaration is used for
1812 // inheriting constructors.
1813 for (const auto *Shadow : D->shadows()) {
1814 if (const auto *ConstructorShadow =
1815 dyn_cast<ConstructorUsingShadowDecl>(Shadow)) {
1816 assert(Shadow->getDeclContext() == ConstructorShadow->getDeclContext());
1817 Out << *ConstructorShadow->getNominatedBaseClass();
1818 return;
1819 }
1820 }
1821 Out << *D;
1822}
1823
1824void DeclPrinter::VisitUsingEnumDecl(UsingEnumDecl *D) {
1825 Out << "using enum " << D->getEnumDecl();
1826}
1827
1828void
1829DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
1830 Out << "using typename ";
1831 D->getQualifier().print(Out, Policy);
1832 Out << D->getDeclName();
1833}
1834
1835void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1836 if (!D->isAccessDeclaration())
1837 Out << "using ";
1838 D->getQualifier().print(Out, Policy);
1839 Out << D->getDeclName();
1840}
1841
1842void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) {
1843 // ignore
1844}
1845
1846void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
1847 Out << "#pragma omp threadprivate";
1848 if (!D->varlist_empty()) {
1850 E = D->varlist_end();
1851 I != E; ++I) {
1852 Out << (I == D->varlist_begin() ? '(' : ',');
1853 NamedDecl *ND = cast<DeclRefExpr>(*I)->getDecl();
1854 ND->printQualifiedName(Out);
1855 }
1856 Out << ")";
1857 }
1858}
1859
1860void DeclPrinter::VisitHLSLBufferDecl(HLSLBufferDecl *D) {
1861 if (D->isCBuffer())
1862 Out << "cbuffer ";
1863 else
1864 Out << "tbuffer ";
1865
1866 Out << *D;
1867
1868 if (std::optional<std::string> Attrs = prettyPrintAttributes(D))
1869 Out << ' ' << *Attrs;
1870
1871 Out << " {\n";
1872 VisitDeclContext(D);
1873 Indent() << "}";
1874}
1875
1876void DeclPrinter::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
1877 Out << "#pragma omp allocate";
1878 if (!D->varlist_empty()) {
1880 E = D->varlist_end();
1881 I != E; ++I) {
1882 Out << (I == D->varlist_begin() ? '(' : ',');
1883 NamedDecl *ND = cast<DeclRefExpr>(*I)->getDecl();
1884 ND->printQualifiedName(Out);
1885 }
1886 Out << ")";
1887 }
1888 if (!D->clauselist_empty()) {
1889 OMPClausePrinter Printer(Out, Policy,
1890 Context.getLangOpts().getOpenMPVersion());
1891 for (OMPClause *C : D->clauselists()) {
1892 Out << " ";
1893 Printer.Visit(C);
1894 }
1895 }
1896}
1897
1898void DeclPrinter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
1899 Out << "#pragma omp requires ";
1900 if (!D->clauselist_empty()) {
1901 OMPClausePrinter Printer(Out, Policy,
1902 Context.getLangOpts().getOpenMPVersion());
1903 for (auto I = D->clauselist_begin(), E = D->clauselist_end(); I != E; ++I)
1904 Printer.Visit(*I);
1905 }
1906}
1907
1908void DeclPrinter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
1909 if (!D->isInvalidDecl()) {
1910 Out << "#pragma omp declare reduction (";
1912 const char *OpName =
1914 assert(OpName && "not an overloaded operator");
1915 Out << OpName;
1916 } else {
1917 assert(D->getDeclName().isIdentifier());
1918 D->printName(Out, Policy);
1919 }
1920 Out << " : ";
1921 D->getType().print(Out, Policy);
1922 Out << " : ";
1923 D->getCombiner()->printPretty(Out, nullptr, Policy, 0, "\n", &Context);
1924 Out << ")";
1925 if (auto *Init = D->getInitializer()) {
1926 Out << " initializer(";
1927 switch (D->getInitializerKind()) {
1929 Out << "omp_priv(";
1930 break;
1932 Out << "omp_priv = ";
1933 break;
1935 break;
1936 }
1937 Init->printPretty(Out, nullptr, Policy, 0, "\n", &Context);
1939 Out << ")";
1940 Out << ")";
1941 }
1942 }
1943}
1944
1945void DeclPrinter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
1946 if (!D->isInvalidDecl()) {
1947 Out << "#pragma omp declare mapper (";
1948 D->printName(Out, Policy);
1949 Out << " : ";
1950 D->getType().print(Out, Policy);
1951 Out << " ";
1952 Out << D->getVarName();
1953 Out << ")";
1954 if (!D->clauselist_empty()) {
1955 OMPClausePrinter Printer(Out, Policy,
1956 Context.getLangOpts().getOpenMPVersion());
1957 for (auto *C : D->clauselists()) {
1958 Out << " ";
1959 Printer.Visit(C);
1960 }
1961 }
1962 }
1963}
1964
1965void DeclPrinter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
1966 D->getInit()->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
1967}
1968
1969void DeclPrinter::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *TTP) {
1970 if (const TypeConstraint *TC = TTP->getTypeConstraint())
1971 TC->print(Out, Policy);
1972 else if (TTP->wasDeclaredWithTypename())
1973 Out << "typename";
1974 else
1975 Out << "class";
1976
1977 if (TTP->isParameterPack())
1978 Out << " ...";
1979 else if (TTP->getDeclName())
1980 Out << ' ';
1981
1982 if (TTP->getDeclName()) {
1983 if (Policy.CleanUglifiedParameters && TTP->getIdentifier())
1984 Out << TTP->getIdentifier()->deuglifiedName();
1985 else
1986 Out << TTP->getDeclName();
1987 }
1988
1989 if (TTP->hasDefaultArgument() && !TTP->defaultArgumentWasInherited()) {
1990 Out << " = ";
1991 TTP->getDefaultArgument().getArgument().print(Policy, Out,
1992 /*IncludeType=*/false);
1993 }
1994}
1995
1996void DeclPrinter::VisitNonTypeTemplateParmDecl(
1997 const NonTypeTemplateParmDecl *NTTP) {
1998 StringRef Name;
1999 if (IdentifierInfo *II = NTTP->getIdentifier())
2000 Name =
2001 Policy.CleanUglifiedParameters ? II->deuglifiedName() : II->getName();
2002 printDeclType(NTTP->getType(), Name, NTTP->isParameterPack());
2003
2004 if (NTTP->hasDefaultArgument() && !NTTP->defaultArgumentWasInherited()) {
2005 Out << " = ";
2006 NTTP->getDefaultArgument().getArgument().print(Policy, Out,
2007 /*IncludeType=*/false);
2008 }
2009}
2010
2011void DeclPrinter::VisitTemplateTemplateParmDecl(
2012 const TemplateTemplateParmDecl *TTPD) {
2013 VisitTemplateDecl(TTPD);
2014 if (TTPD->hasDefaultArgument() && !TTPD->defaultArgumentWasInherited()) {
2015 Out << " = ";
2016 TTPD->getDefaultArgument().getArgument().print(Policy, Out,
2017 /*IncludeType=*/false);
2018 }
2019}
2020
2021void DeclPrinter::VisitOpenACCDeclareDecl(OpenACCDeclareDecl *D) {
2022 if (!D->isInvalidDecl()) {
2023 Out << "#pragma acc declare";
2024 if (!D->clauses().empty()) {
2025 Out << ' ';
2026 OpenACCClausePrinter Printer(Out, Policy);
2027 Printer.VisitClauseList(D->clauses());
2028 }
2029 }
2030}
2031void DeclPrinter::VisitOpenACCRoutineDecl(OpenACCRoutineDecl *D) {
2032 if (!D->isInvalidDecl()) {
2033 Out << "#pragma acc routine";
2034
2035 Out << "(";
2036
2037 // The referenced function was named here, but this makes us tolerant of
2038 // errors.
2039 if (D->getFunctionReference())
2040 D->getFunctionReference()->printPretty(Out, nullptr, Policy, Indentation,
2041 "\n", &Context);
2042 else
2043 Out << "<error>";
2044
2045 Out << ")";
2046
2047 if (!D->clauses().empty()) {
2048 Out << ' ';
2049 OpenACCClausePrinter Printer(Out, Policy);
2050 Printer.VisitClauseList(D->clauses());
2051 }
2052 }
2053}
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
static DeclPrinter::AttrPosAsWritten getPosAsWritten(const Attr *A, const Decl *D)
static QualType getDeclType(Decl *D)
static QualType GetBaseType(QualType T)
static void printExplicitSpecifier(ExplicitSpecifier ES, llvm::raw_ostream &Out, PrintingPolicy &Policy, unsigned Indentation, const ASTContext &Context)
Defines the C++ template declaration subclasses.
Defines the clang::Expr interface and subclasses for C++ expressions.
FormatToken * Next
The next token in the unwrapped line.
Defines the clang::Module class, which describes a module in the source code.
Defines the SourceManager interface.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition ASTContext.h:239
const LangOptions & getLangOpts() const
const clang::PrintingPolicy & getPrintingPolicy() const
Definition ASTContext.h:899
QualType getUnqualifiedObjCPointerType(QualType type) const
getUnqualifiedObjCPointerType - Returns version of Objective-C pointer type with lifetime qualifier r...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition TypeBase.h:3800
Attr - This represents one attribute.
Definition Attr.h:46
SourceLocation getLoc() const
shadow_range shadows() const
Definition DeclCXX.h:3591
Pointer to a block type.
Definition TypeBase.h:3633
Represents a call to a C++ constructor.
Definition ExprCXX.h:1552
Represents a C++ constructor within a class.
Definition DeclCXX.h:2641
Represents a C++ conversion function within a class.
Definition DeclCXX.h:2976
Represents a C++ deduction guide declaration.
Definition DeclCXX.h:2000
TemplateDecl * getDeducedTemplate() const
Get the template for which this guide performs deduction.
Definition DeclCXX.h:2064
Represents a C++26 expansion statement declaration.
CXXExpansionStmtPattern * getExpansionPattern()
Represents a C++ struct/union/class.
Definition DeclCXX.h:258
CXXBaseSpecifier * base_class_iterator
Iterator that traverses the base classes of a class.
Definition DeclCXX.h:517
bool isLambda() const
Determine whether this class describes a lambda function object.
Definition DeclCXX.h:1027
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
Definition DeclCXX.cpp:1744
Declaration of a class template.
bool isThisDeclarationADefinition() const
Returns whether this template declaration defines the primary class pattern.
spec_range specializations() const
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a class template specialization, which refers to a class template with a given set of temp...
decl_iterator - Iterates through the declarations stored within this context.
Definition DeclBase.h:2360
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition DeclBase.h:1466
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition DeclBase.h:2126
bool isTranslationUnit() const
Definition DeclBase.h:2202
DeclContext(Decl::Kind K)
void dumpDeclContext() const
decl_iterator decls_end() const
Definition DeclBase.h:2405
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
Definition DeclBase.h:2403
decl_iterator decls_begin() const
A simple visitor class that helps create declaration visitors.
Definition DeclVisitor.h:68
Decl - This represents one declaration (or definition), e.g.
Definition DeclBase.h:86
Decl()=delete
bool hasAttrs() const
Definition DeclBase.h:526
ASTContext & getASTContext() const LLVM_READONLY
Definition DeclBase.cpp:550
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition DeclBase.h:601
ObjCDeclQualifier
ObjCDeclQualifier - 'Qualifiers' written next to the return and parameter types in method declaration...
Definition DeclBase.h:198
@ OBJC_TQ_CSNullability
The nullability qualifier is set when the nullability of the result or parameter was expressed via a ...
Definition DeclBase.h:210
bool isInvalidDecl() const
Definition DeclBase.h:596
SourceLocation getLocation() const
Definition DeclBase.h:447
static void printGroup(Decl **Begin, unsigned NumDecls, raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation=0)
AccessSpecifier getAccess() const
Definition DeclBase.h:515
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
AttrVec & getAttrs()
Definition DeclBase.h:532
bool hasAttr() const
Definition DeclBase.h:585
std::string getAsString() const
Retrieve the human-readable string for this name.
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
NameKind getNameKind() const
Determine what kind of name this is.
bool isIdentifier() const
Predicate functions for querying what type of name this is.
const AssociatedConstraint & getTrailingRequiresClause() const
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
Definition Decl.h:856
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
Definition Decl.h:863
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
Definition Decl.h:838
TypeSourceInfo * getTypeSourceInfo() const
Definition Decl.h:810
Represents an empty-declaration.
Definition Decl.h:5314
An instance of this object exists for each enum constant that is defined.
Definition Decl.h:3558
const Expr * getInitExpr() const
Definition Decl.h:3576
Represents an enum.
Definition Decl.h:4146
bool isScoped() const
Returns true if this is a C++11 scoped enumeration.
Definition Decl.h:4364
bool isScopedUsingClassTag() const
Returns true if this is a C++11 scoped enumeration.
Definition Decl.h:4367
bool isFixed() const
Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...
Definition Decl.h:4373
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
Definition Decl.h:4319
Represents an explicit instantiation of a template entity in source code.
TypeSourceInfo * getTypeAsWritten() const
The declared type (return type or variable type) for function / variable templates.
std::optional< unsigned > getNumTemplateArgs() const
Returns the number of explicit template arguments, or std::nullopt if this entity has no template arg...
TemplateArgumentLoc getTemplateArg(unsigned I) const
NamedDecl * getSpecialization() const
NestedNameSpecifierLoc getQualifierLoc() const
Returns the qualifier regardless of where it is stored.
Store information needed for an explicit specifier.
Definition DeclCXX.h:1948
const Expr * getExpr() const
Definition DeclCXX.h:1957
static ExplicitSpecifier getFromDecl(const FunctionDecl *Function)
Definition DeclCXX.cpp:2370
bool isSpecified() const
Determine if the declaration had an explicit specifier of any kind.
Definition DeclCXX.h:1961
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition ExprCXX.h:3714
This represents one expression.
Definition Expr.h:113
Represents a member of a struct/union/class.
Definition Decl.h:3295
bool isMutable() const
Determines whether this field is mutable (C++ only).
Definition Decl.h:3395
Expr * getInClassInitializer() const
Get the C++11 default member initializer for this member, or null if one has not been set.
Definition Decl.cpp:4789
bool isBitField() const
Determines whether this field is a bitfield.
Definition Decl.h:3398
InClassInitStyle getInClassInitStyle() const
Get the kind of (C++11) default member initializer that this field has.
Definition Decl.h:3469
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
Definition Decl.h:3411
const Expr * getAsmStringExpr() const
Definition Decl.h:4755
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
Definition DeclFriend.h:46
virtual NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
Definition DeclFriend.h:102
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Definition DeclFriend.h:96
bool isPackExpansion() const
Definition DeclFriend.h:113
Declaration of a friend template.
TemplateName getFriendTemplateName() const
ArrayRef< TemplateParameterList * > getTemplateParameterLists() const
Represents a function declaration or definition.
Definition Decl.h:2059
const ParmVarDecl * getParamDecl(unsigned i) const
Definition Decl.h:2928
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition Decl.cpp:3268
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
Definition Decl.cpp:4246
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition Decl.cpp:4234
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition Decl.h:2428
bool isImmediateFunction() const
Definition Decl.cpp:3384
StringLiteral * getDeletedMessage() const
Get the message that indicates why this function was deleted.
Definition Decl.h:2889
bool isExplicitlyDefaulted() const
Whether this function is explicitly defaulted.
Definition Decl.h:2516
bool hasWrittenPrototype() const
Whether this function has a written prototype.
Definition Decl.h:2575
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
Definition Decl.h:2570
bool doesThisDeclarationHaveABody() const
Returns whether this specific declaration of the function has a body.
Definition Decl.h:2440
bool isConstexprSpecified() const
Definition Decl.h:2606
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Definition Decl.cpp:4370
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Definition Decl.h:3019
bool isDeletedAsWritten() const
Definition Decl.h:2671
bool isPureVirtual() const
Whether this virtual function is pure, i.e.
Definition Decl.h:2480
bool isConsteval() const
Definition Decl.h:2609
bool isVirtualAsWritten() const
Whether this function is marked as virtual explicitly.
Definition Decl.h:2471
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition Decl.cpp:3870
DeclarationNameInfo getNameInfo() const
Definition Decl.h:2325
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
Definition Decl.cpp:3235
bool isInlineSpecified() const
Determine whether the "inline" keyword was specified for this function.
Definition Decl.h:3030
const ASTTemplateArgumentListInfo * getTemplateSpecializationArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
Definition Decl.cpp:4380
Represents a prototype with parameter type info, e.g.
Definition TypeBase.h:5385
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition TypeBase.h:5692
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition TypeBase.h:5805
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition TypeBase.h:5743
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition TypeBase.h:5735
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
Definition TypeBase.h:5701
bool isVariadic() const
Whether this function prototype is variadic.
Definition TypeBase.h:5789
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition TypeBase.h:5750
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition TypeBase.h:5819
Declaration of a template function.
FunctionDecl * getTemplatedDecl() const
Get the underlying function declaration of the template.
spec_range specializations() const
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition TypeBase.h:4581
bool isConst() const
Definition TypeBase.h:4943
bool isRestrict() const
Definition TypeBase.h:4945
bool isVolatile() const
Definition TypeBase.h:4944
HLSLBufferDecl - Represent a cbuffer or tbuffer declaration.
Definition Decl.h:5329
bool isCBuffer() const
Definition Decl.h:5373
One of these records is kept for each identifier that is lexed.
StringRef deuglifiedName() const
If the identifier is an "uglified" reserved name, return a cleaned form.
Describes a module import declaration, which makes the contents of the named module visible in the cu...
Definition Decl.h:5188
Module * getImportedModule() const
Retrieve the module that was imported by the import declaration.
Definition Decl.h:5246
Represents the declaration of a label.
Definition Decl.h:525
llvm::omp::Version getOpenMPVersion() const
Return the OpenMP version.
Represents a linkage specification.
Definition DeclCXX.h:3044
LinkageSpecLanguageIDs getLanguage() const
Return the language specified by this linkage specification.
Definition DeclCXX.h:3067
bool hasBraces() const
Determines whether this linkage specification had braces in its syntactic form.
Definition DeclCXX.h:3078
std::string getFullModuleName(bool AllowStringLiterals=false) const
Retrieve the full name of this module, including the path from its top-level module.
Definition Module.cpp:240
This represents a decl that may have a name.
Definition Decl.h:275
bool isModulePrivate() const
Whether this declaration was marked as being private to the module in which it was defined.
Definition DeclBase.h:656
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition Decl.h:296
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition Decl.h:302
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition Decl.h:341
std::string getQualifiedNameAsString() const
Definition Decl.cpp:1684
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
Definition Decl.h:318
void printQualifiedName(raw_ostream &OS) const
Returns a human-readable qualified name for this declaration, like A::B::i, for i being member of nam...
Definition Decl.cpp:1691
virtual void printName(raw_ostream &OS, const PrintingPolicy &Policy) const
Pretty-print the unqualified name of this declaration.
Definition Decl.cpp:1676
Represents a C++ namespace alias.
Definition DeclCXX.h:3230
NamespaceBaseDecl * getAliasedNamespace() const
Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...
Definition DeclCXX.h:3323
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of the namespace.
Definition DeclCXX.h:3295
Represent a C++ namespace.
Definition Decl.h:593
bool isInline() const
Returns true if this is an inline namespace declaration.
Definition Decl.h:649
NestedNameSpecifier getNestedNameSpecifier() const
Retrieve the nested-name-specifier to which this instance refers.
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false, bool PrintFinalScopeResOp=true) const
Print this nested name specifier to the given output stream.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
This represents 'pragma omp allocate ...' directive.
Definition DeclOpenMP.h:536
bool varlist_empty() const
Definition DeclOpenMP.h:574
bool clauselist_empty() const
Definition DeclOpenMP.h:576
varlist_iterator varlist_begin()
Definition DeclOpenMP.h:584
MutableArrayRef< Expr * >::iterator varlist_iterator
Definition DeclOpenMP.h:564
clauselist_range clauselists()
Definition DeclOpenMP.h:589
varlist_iterator varlist_end()
Definition DeclOpenMP.h:585
Pseudo declaration for capturing expressions.
Definition DeclOpenMP.h:445
This is a basic class for representing single OpenMP clause.
This represents 'pragma omp declare mapper ...' directive.
Definition DeclOpenMP.h:349
clauselist_range clauselists()
Definition DeclOpenMP.h:395
DeclarationName getVarName()
Get the name of the variable declared in the mapper.
Definition DeclOpenMP.h:421
This represents 'pragma omp declare reduction ...' directive.
Definition DeclOpenMP.h:239
Expr * getInitializer()
Get initializer expression (if specified) of the declare reduction construct.
Definition DeclOpenMP.h:300
Expr * getCombiner()
Get combiner expression of the declare reduction construct.
Definition DeclOpenMP.h:282
OMPDeclareReductionInitKind getInitializerKind() const
Get initializer kind.
Definition DeclOpenMP.h:303
This represents 'pragma omp requires...' directive.
Definition DeclOpenMP.h:479
clauselist_iterator clauselist_begin()
Definition DeclOpenMP.h:510
bool clauselist_empty() const
Definition DeclOpenMP.h:502
clauselist_iterator clauselist_end()
Definition DeclOpenMP.h:511
This represents 'pragma omp threadprivate ...' directive.
Definition DeclOpenMP.h:110
MutableArrayRef< Expr * >::iterator varlist_iterator
Definition DeclOpenMP.h:138
varlist_iterator varlist_end()
Definition DeclOpenMP.h:153
varlist_iterator varlist_begin()
Definition DeclOpenMP.h:152
ObjCCategoryDecl - Represents a category declaration.
Definition DeclObjC.h:2335
ObjCInterfaceDecl * getClassInterface()
Definition DeclObjC.h:2378
ObjCTypeParamList * getTypeParamList() const
Retrieve the type parameter list associated with this category or extension.
Definition DeclObjC.h:2383
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition DeclObjC.h:2551
ObjCCompatibleAliasDecl - Represents alias of a class.
Definition DeclObjC.h:2781
const ObjCInterfaceDecl * getClassInterface() const
Definition DeclObjC.h:2799
const ObjCInterfaceDecl * getClassInterface() const
Definition DeclObjC.h:2492
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition DeclObjC.h:2603
std::string getNameAsString() const
Get the name of the class associated with this interface.
Definition DeclObjC.h:2735
ivar_range ivars() const
Definition DeclObjC.h:2755
unsigned ivar_size() const
Definition DeclObjC.h:2765
const ObjCInterfaceDecl * getSuperClass() const
Definition DeclObjC.h:2741
Represents an ObjC class declaration.
Definition DeclObjC.h:1160
unsigned ivar_size() const
Definition DeclObjC.h:1475
ivar_range ivars() const
Definition DeclObjC.h:1457
ObjCTypeParamList * getTypeParamListAsWritten() const
Retrieve the type parameters written on this particular declaration of the class.
Definition DeclObjC.h:1309
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
Definition DeclObjC.h:1529
const ObjCProtocolList & getReferencedProtocols() const
Definition DeclObjC.h:1339
const ObjCObjectType * getSuperClassType() const
Retrieve the superclass type.
Definition DeclObjC.h:1571
ObjCInterfaceDecl * getSuperClass() const
Definition DeclObjC.cpp:349
bool empty() const
Definition DeclObjC.h:71
ObjCList - This is a simple template class used to hold various lists of decls etc,...
Definition DeclObjC.h:82
iterator end() const
Definition DeclObjC.h:91
iterator begin() const
Definition DeclObjC.h:90
T *const * iterator
Definition DeclObjC.h:88
ObjCMethodDecl - Represents an instance or class method declaration.
Definition DeclObjC.h:140
ObjCDeclQualifier getObjCDeclQualifier() const
Definition DeclObjC.h:246
ArrayRef< ParmVarDecl * > parameters() const
Definition DeclObjC.h:376
bool isVariadic() const
Definition DeclObjC.h:434
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
Definition DeclObjC.cpp:927
Selector getSelector() const
Definition DeclObjC.h:330
bool isInstanceMethod() const
Definition DeclObjC.h:429
QualType getReturnType() const
Definition DeclObjC.h:332
Represents a pointer to an Objective C object.
Definition TypeBase.h:8059
Represents one property declaration in an Objective-C interface.
Definition DeclObjC.h:734
Selector getSetterName() const
Definition DeclObjC.h:899
QualType getType() const
Definition DeclObjC.h:810
Selector getGetterName() const
Definition DeclObjC.h:891
ObjCPropertyAttribute::Kind getPropertyAttributes() const
Definition DeclObjC.h:821
PropertyControl getPropertyImplementation() const
Definition DeclObjC.h:918
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition DeclObjC.h:2811
ObjCIvarDecl * getPropertyIvarDecl() const
Definition DeclObjC.h:2885
Kind getPropertyImplementation() const
Definition DeclObjC.h:2881
ObjCPropertyDecl * getPropertyDecl() const
Definition DeclObjC.h:2876
Represents an Objective-C protocol declaration.
Definition DeclObjC.h:2090
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
Definition DeclObjC.h:2267
const ObjCProtocolList & getReferencedProtocols() const
Definition DeclObjC.h:2159
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
Definition DeclObjC.h:665
ArrayRef< const OpenACCClause * > clauses() const
Definition DeclOpenACC.h:62
const Expr * getFunctionReference() const
Sugar for parentheses used when specifying types.
Definition TypeBase.h:3376
Represents a parameter to a function.
Definition Decl.h:1820
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition TypeBase.h:3396
A (possibly-)qualified type.
Definition TypeBase.h:938
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition TypeBase.h:1005
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
StreamedQualTypeHelper stream(const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition TypeBase.h:1404
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition TypeBase.h:1348
Represents a struct/union/class.
Definition Decl.h:4460
Base for LValueReferenceType and RValueReferenceType.
Definition TypeBase.h:3658
std::string getAsString() const
Derive the full selector name (e.g.
void print(llvm::raw_ostream &OS) const
Prints the full selector name (e.g. "foo:bar:").
Encodes a location in the source.
Represents a C++11 static_assert declaration.
Definition DeclCXX.h:4165
void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
void printPrettyControlled(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const
StringLiteral - This represents a string literal expression, e.g.
Definition Expr.h:1819
StringRef getKindName() const
Definition Decl.h:4048
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition Decl.h:3953
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
Definition Decl.h:4098
A template argument list.
const TemplateArgument & getArgument() const
void print(const PrintingPolicy &Policy, raw_ostream &Out, bool IncludeType) const
Print this template argument to the given output stream.
The base class of all kinds of template declarations (e.g., class, function, etc.).
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Represents a C++ template name within the type system.
TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const
Retrieve the underlying template declaration that this template name refers to, if known.
bool isNull() const
Determine whether this template name is NULL.
void print(raw_ostream &OS, const PrintingPolicy &Policy, Qualified Qual=Qualified::AsWritten) const
Print the template name.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
void print(raw_ostream &Out, const ASTContext &Context, bool OmitTemplateKW=false) const
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
Declaration of a template type parameter.
bool wasDeclaredWithTypename() const
Whether this template type parameter was declared with the 'typename' keyword.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
const TypeConstraint * getTypeConstraint() const
Returns the type constraint associated with this template parameter (if any).
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool defaultArgumentWasInherited() const
Determines whether the default argument was inherited from a previous declaration of this template.
bool isParameterPack() const
Returns whether this is a parameter pack.
A declaration that models statements at global scope.
Definition Decl.h:4770
The top declaration context.
Definition Decl.h:106
Represents the declaration of a typedef-name via a C++11 alias-declaration.
Definition Decl.h:3823
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Definition ASTConcept.h:227
A container of type source information.
Definition TypeBase.h:8389
QualType getType() const
Return the type wrapped by this type source info.
Definition TypeBase.h:8400
const T * getAs() const
Member-template getAs<specific type>'.
Definition TypeBase.h:9254
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition Decl.h:3802
Base class for declarations which introduce a typedef-name.
Definition Decl.h:3697
TypeSourceInfo * getTypeSourceInfo() const
Definition Decl.h:3747
Represents a dependent using declaration which was marked with typename.
Definition DeclCXX.h:4066
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name.
Definition DeclCXX.h:4103
Represents a dependent using declaration which was not marked with typename.
Definition DeclCXX.h:3969
bool isAccessDeclaration() const
Return true if it is a C++03 access declaration (no 'using').
Definition DeclCXX.h:4006
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name.
Definition DeclCXX.h:4013
Represents a C++ using-declaration.
Definition DeclCXX.h:3620
bool hasTypename() const
Return true if the using declaration has 'typename'.
Definition DeclCXX.h:3669
bool isAccessDeclaration() const
Return true if it is a C++03 access declaration (no 'using').
Definition DeclCXX.h:3666
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name.
Definition DeclCXX.h:3657
Represents C++ using-directive.
Definition DeclCXX.h:3125
NamedDecl * getNominatedNamespaceAsWritten()
Definition DeclCXX.h:3178
NestedNameSpecifier getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of the namespace.
Definition DeclCXX.h:3174
Represents a C++ using-enum-declaration.
Definition DeclCXX.h:3821
EnumDecl * getEnumDecl() const
Definition DeclCXX.h:3863
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition DeclCXX.h:3428
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition Decl.h:713
QualType getType() const
Definition Decl.h:724
Represents a variable declaration or definition.
Definition Decl.h:933
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
Definition Decl.h:1594
InitializationStyle getInitStyle() const
The style of initialization for this declaration.
Definition Decl.h:1491
static const char * getStorageClassSpecifierString(StorageClass SC)
Return the string used to specify the storage class SC.
Definition Decl.cpp:2103
@ CInit
C-style initialization with assignment.
Definition Decl.h:938
@ CallInit
Call-style initialization (C++98)
Definition Decl.h:941
bool isCXXForRangeDecl() const
Determine whether this variable is the for-range-declaration in a C++0x for-range statement.
Definition Decl.h:1547
ThreadStorageClassSpecifier getTSCSpec() const
Definition Decl.h:1184
const Expr * getInit() const
Definition Decl.h:1392
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Definition Decl.h:1175
Represents a GCC generic vector type.
Definition TypeBase.h:4253
@ kind_nullability
Indicates that the nullability of the type was spelled with a property attribute rather than a type q...
@ OS
Indicates that the tracking object is a descendant of a referenced-counted OSObject,...
RangeSelector name(std::string ID)
Given a node with a "name", (like NamedDecl, DeclRefExpr, CxxCtorInitializer, and TypeLoc) selects th...
Top level wrappers for InstallAPI frontend operations.
bool isa(CodeGen::Address addr)
Definition Address.h:330
llvm::StringRef getAccessSpelling(AccessSpecifier AS)
Definition Specifiers.h:420
@ Unspecified
Whether values of this type can be null is (explicitly) unspecified.
Definition Specifiers.h:356
@ ICIS_ListInit
Direct list-initialization.
Definition Specifiers.h:275
@ RQ_None
No ref-qualifier was provided.
Definition TypeBase.h:1801
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition TypeBase.h:1804
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition TypeBase.h:1807
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition Specifiers.h:124
@ AS_none
Definition Specifiers.h:128
SmallVector< Attr *, 4 > AttrVec
AttrVec - A vector of Attr, which is how they are stored on the AST.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
StorageClass
Storage classes.
Definition Specifiers.h:249
@ SC_Auto
Definition Specifiers.h:257
@ SC_PrivateExtern
Definition Specifiers.h:254
@ SC_Extern
Definition Specifiers.h:252
@ SC_Register
Definition Specifiers.h:258
@ SC_Static
Definition Specifiers.h:253
@ SC_None
Definition Specifiers.h:251
@ TSCS_thread_local
C++11 thread_local.
Definition Specifiers.h:242
@ TSCS_unspecified
Definition Specifiers.h:237
@ TSCS__Thread_local
C11 _Thread_local.
Definition Specifiers.h:245
@ TSCS___thread
GNU __thread.
Definition Specifiers.h:239
raw_ostream & Indent(raw_ostream &Out, const unsigned int Space, bool IsDot)
Definition JsonSupport.h:21
@ Default
Set to the current date and time.
llvm::StringRef getNullabilitySpelling(NullabilityKind kind, bool isContextSensitive=false)
Retrieve the spelling of the given nullability kind.
const FunctionProtoType * T
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Concept
The name was classified as a concept name.
Definition Sema.h:585
@ TNK_Var_template
The name refers to a variable template whose specialization produces a variable.
@ TNK_Concept_template
The name refers to a concept.
llvm::StringRef getAsString(SyncScope S)
Definition SyncScope.h:63
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition Specifiers.h:195
@ Invariant
The parameter is invariant: must match exactly.
Definition DeclObjC.h:558
@ Contravariant
The parameter is contravariant, e.g., X<T> is a subtype of X when the type parameter is covariant and...
Definition DeclObjC.h:566
@ Covariant
The parameter is covariant, e.g., X<T> is a subtype of X when the type parameter is covariant and T i...
Definition DeclObjC.h:562
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
U cast(CodeGen::Address addr)
Definition Address.h:327
@ EST_MSAny
Microsoft throw(...) extension.
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
ArrayRef< TemplateArgumentLoc > arguments() const
void printName(raw_ostream &OS, PrintingPolicy Policy) const
printName - Print the human-readable name to a stream.
Describes how types, statements, expressions, and declarations should be printed.
unsigned SuppressDeclAttributes
Whether to suppress attributes in decl printing.
unsigned FullyQualifiedName
When true, print the fully qualified name of function declarations.
unsigned PolishForDeclaration
When true, do certain refinement needed for producing proper declaration tag; such as,...
unsigned CleanUglifiedParameters
Whether to strip underscores when printing reserved parameter names.
unsigned SuppressSpecifiers
Whether we should suppress printing of the actual specifiers for the given type or declaration.
unsigned SuppressScope
Suppresses printing of scope specifiers.
unsigned Indentation
The number of spaces to use to indent each line.
unsigned SuppressInitializers
Suppress printing of variable initializers.
unsigned TerseOutput
Provide a 'terse' output.
unsigned PrintAsCanonical
Whether to print entities as written or canonically.