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