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