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