clang 17.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"
24#include "llvm/Support/raw_ostream.h"
25using namespace clang;
26
27namespace {
28 class DeclPrinter : public DeclVisitor<DeclPrinter> {
29 raw_ostream &Out;
30 PrintingPolicy Policy;
31 const ASTContext &Context;
32 unsigned Indentation;
33 bool PrintInstantiation;
34
35 raw_ostream& Indent() { return Indent(Indentation); }
36 raw_ostream& Indent(unsigned Indentation);
37 void ProcessDeclGroup(SmallVectorImpl<Decl*>& Decls);
38
39 void Print(AccessSpecifier AS);
40 void PrintConstructorInitializers(CXXConstructorDecl *CDecl,
41 std::string &Proto);
42
43 /// Print an Objective-C method type in parentheses.
44 ///
45 /// \param Quals The Objective-C declaration qualifiers.
46 /// \param T The type to print.
47 void PrintObjCMethodType(ASTContext &Ctx, Decl::ObjCDeclQualifier Quals,
48 QualType T);
49
50 void PrintObjCTypeParams(ObjCTypeParamList *Params);
51
52 public:
53 DeclPrinter(raw_ostream &Out, const PrintingPolicy &Policy,
54 const ASTContext &Context, unsigned Indentation = 0,
55 bool PrintInstantiation = false)
56 : Out(Out), Policy(Policy), Context(Context), Indentation(Indentation),
57 PrintInstantiation(PrintInstantiation) {}
58
59 void VisitDeclContext(DeclContext *DC, bool Indent = true);
60
61 void VisitTranslationUnitDecl(TranslationUnitDecl *D);
62 void VisitTypedefDecl(TypedefDecl *D);
63 void VisitTypeAliasDecl(TypeAliasDecl *D);
64 void VisitEnumDecl(EnumDecl *D);
65 void VisitRecordDecl(RecordDecl *D);
66 void VisitEnumConstantDecl(EnumConstantDecl *D);
67 void VisitEmptyDecl(EmptyDecl *D);
68 void VisitFunctionDecl(FunctionDecl *D);
69 void VisitFriendDecl(FriendDecl *D);
70 void VisitFieldDecl(FieldDecl *D);
71 void VisitVarDecl(VarDecl *D);
72 void VisitLabelDecl(LabelDecl *D);
73 void VisitParmVarDecl(ParmVarDecl *D);
74 void VisitFileScopeAsmDecl(FileScopeAsmDecl *D);
75 void VisitTopLevelStmtDecl(TopLevelStmtDecl *D);
76 void VisitImportDecl(ImportDecl *D);
77 void VisitStaticAssertDecl(StaticAssertDecl *D);
78 void VisitNamespaceDecl(NamespaceDecl *D);
79 void VisitUsingDirectiveDecl(UsingDirectiveDecl *D);
80 void VisitNamespaceAliasDecl(NamespaceAliasDecl *D);
81 void VisitCXXRecordDecl(CXXRecordDecl *D);
82 void VisitLinkageSpecDecl(LinkageSpecDecl *D);
83 void VisitTemplateDecl(const TemplateDecl *D);
84 void VisitFunctionTemplateDecl(FunctionTemplateDecl *D);
85 void VisitClassTemplateDecl(ClassTemplateDecl *D);
86 void VisitClassTemplateSpecializationDecl(
88 void VisitClassTemplatePartialSpecializationDecl(
90 void VisitObjCMethodDecl(ObjCMethodDecl *D);
91 void VisitObjCImplementationDecl(ObjCImplementationDecl *D);
92 void VisitObjCInterfaceDecl(ObjCInterfaceDecl *D);
93 void VisitObjCProtocolDecl(ObjCProtocolDecl *D);
94 void VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D);
95 void VisitObjCCategoryDecl(ObjCCategoryDecl *D);
96 void VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D);
97 void VisitObjCPropertyDecl(ObjCPropertyDecl *D);
98 void VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D);
99 void VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D);
100 void VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D);
101 void VisitUsingDecl(UsingDecl *D);
102 void VisitUsingEnumDecl(UsingEnumDecl *D);
103 void VisitUsingShadowDecl(UsingShadowDecl *D);
104 void VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D);
105 void VisitOMPAllocateDecl(OMPAllocateDecl *D);
106 void VisitOMPRequiresDecl(OMPRequiresDecl *D);
107 void VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D);
108 void VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D);
109 void VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D);
110 void VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *TTP);
111 void VisitNonTypeTemplateParmDecl(const NonTypeTemplateParmDecl *NTTP);
112 void VisitHLSLBufferDecl(HLSLBufferDecl *D);
113
114 void printTemplateParameters(const TemplateParameterList *Params,
115 bool OmitTemplateKW = false);
116 void printTemplateArguments(llvm::ArrayRef<TemplateArgument> Args,
117 const TemplateParameterList *Params);
118 void printTemplateArguments(llvm::ArrayRef<TemplateArgumentLoc> Args,
119 const TemplateParameterList *Params);
120 void prettyPrintAttributes(Decl *D);
121 void prettyPrintPragmas(Decl *D);
122 void printDeclType(QualType T, StringRef DeclName, bool Pack = false);
123 };
124}
125
126void Decl::print(raw_ostream &Out, unsigned Indentation,
127 bool PrintInstantiation) const {
128 print(Out, getASTContext().getPrintingPolicy(), Indentation, PrintInstantiation);
129}
130
131void Decl::print(raw_ostream &Out, const PrintingPolicy &Policy,
132 unsigned Indentation, bool PrintInstantiation) const {
133 DeclPrinter Printer(Out, Policy, getASTContext(), Indentation,
134 PrintInstantiation);
135 Printer.Visit(const_cast<Decl*>(this));
136}
137
138void TemplateParameterList::print(raw_ostream &Out, const ASTContext &Context,
139 bool OmitTemplateKW) const {
140 print(Out, Context, Context.getPrintingPolicy(), OmitTemplateKW);
141}
142
143void TemplateParameterList::print(raw_ostream &Out, const ASTContext &Context,
144 const PrintingPolicy &Policy,
145 bool OmitTemplateKW) const {
146 DeclPrinter Printer(Out, Policy, Context);
147 Printer.printTemplateParameters(this, OmitTemplateKW);
148}
149
151 // FIXME: This should be on the Type class!
152 QualType BaseType = T;
153 while (!BaseType->isSpecifierType()) {
154 if (const PointerType *PTy = BaseType->getAs<PointerType>())
155 BaseType = PTy->getPointeeType();
156 else if (const ObjCObjectPointerType *OPT =
157 BaseType->getAs<ObjCObjectPointerType>())
158 BaseType = OPT->getPointeeType();
159 else if (const BlockPointerType *BPy = BaseType->getAs<BlockPointerType>())
160 BaseType = BPy->getPointeeType();
161 else if (const ArrayType *ATy = dyn_cast<ArrayType>(BaseType))
162 BaseType = ATy->getElementType();
163 else if (const FunctionType *FTy = BaseType->getAs<FunctionType>())
164 BaseType = FTy->getReturnType();
165 else if (const VectorType *VTy = BaseType->getAs<VectorType>())
166 BaseType = VTy->getElementType();
167 else if (const ReferenceType *RTy = BaseType->getAs<ReferenceType>())
168 BaseType = RTy->getPointeeType();
169 else if (const AutoType *ATy = BaseType->getAs<AutoType>())
170 BaseType = ATy->getDeducedType();
171 else if (const ParenType *PTy = BaseType->getAs<ParenType>())
172 BaseType = PTy->desugar();
173 else
174 // This must be a syntax error.
175 break;
176 }
177 return BaseType;
178}
179
181 if (TypedefNameDecl* TDD = dyn_cast<TypedefNameDecl>(D))
182 return TDD->getUnderlyingType();
183 if (ValueDecl* VD = dyn_cast<ValueDecl>(D))
184 return VD->getType();
185 return QualType();
186}
187
188void Decl::printGroup(Decl** Begin, unsigned NumDecls,
189 raw_ostream &Out, const PrintingPolicy &Policy,
190 unsigned Indentation) {
191 if (NumDecls == 1) {
192 (*Begin)->print(Out, Policy, Indentation);
193 return;
194 }
195
196 Decl** End = Begin + NumDecls;
197 TagDecl* TD = dyn_cast<TagDecl>(*Begin);
198 if (TD)
199 ++Begin;
200
201 PrintingPolicy SubPolicy(Policy);
202
203 bool isFirst = true;
204 for ( ; Begin != End; ++Begin) {
205 if (isFirst) {
206 if(TD)
207 SubPolicy.IncludeTagDefinition = true;
208 SubPolicy.SuppressSpecifiers = false;
209 isFirst = false;
210 } else {
211 if (!isFirst) Out << ", ";
212 SubPolicy.IncludeTagDefinition = false;
213 SubPolicy.SuppressSpecifiers = true;
214 }
215
216 (*Begin)->print(Out, SubPolicy, Indentation);
217 }
218}
219
220LLVM_DUMP_METHOD void DeclContext::dumpDeclContext() const {
221 // Get the translation unit
222 const DeclContext *DC = this;
223 while (!DC->isTranslationUnit())
224 DC = DC->getParent();
225
226 ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
227 DeclPrinter Printer(llvm::errs(), Ctx.getPrintingPolicy(), Ctx, 0);
228 Printer.VisitDeclContext(const_cast<DeclContext *>(this), /*Indent=*/false);
229}
230
231raw_ostream& DeclPrinter::Indent(unsigned Indentation) {
232 for (unsigned i = 0; i != Indentation; ++i)
233 Out << " ";
234 return Out;
235}
236
237void DeclPrinter::prettyPrintAttributes(Decl *D) {
238 if (Policy.PolishForDeclaration)
239 return;
240
241 if (D->hasAttrs()) {
242 AttrVec &Attrs = D->getAttrs();
243 for (auto *A : Attrs) {
244 if (A->isInherited() || A->isImplicit())
245 continue;
246 switch (A->getKind()) {
247#define ATTR(X)
248#define PRAGMA_SPELLING_ATTR(X) case attr::X:
249#include "clang/Basic/AttrList.inc"
250 break;
251 default:
252 A->printPretty(Out, Policy);
253 break;
254 }
255 }
256 }
257}
258
259void DeclPrinter::prettyPrintPragmas(Decl *D) {
260 if (Policy.PolishForDeclaration)
261 return;
262
263 if (D->hasAttrs()) {
264 AttrVec &Attrs = D->getAttrs();
265 for (auto *A : Attrs) {
266 switch (A->getKind()) {
267#define ATTR(X)
268#define PRAGMA_SPELLING_ATTR(X) case attr::X:
269#include "clang/Basic/AttrList.inc"
270 A->printPretty(Out, Policy);
271 Indent();
272 break;
273 default:
274 break;
275 }
276 }
277 }
278}
279
280void DeclPrinter::printDeclType(QualType T, StringRef DeclName, bool Pack) {
281 // Normally, a PackExpansionType is written as T[3]... (for instance, as a
282 // template argument), but if it is the type of a declaration, the ellipsis
283 // is placed before the name being declared.
284 if (auto *PET = T->getAs<PackExpansionType>()) {
285 Pack = true;
286 T = PET->getPattern();
287 }
288 T.print(Out, Policy, (Pack ? "..." : "") + DeclName, Indentation);
289}
290
291void DeclPrinter::ProcessDeclGroup(SmallVectorImpl<Decl*>& Decls) {
292 this->Indent();
293 Decl::printGroup(Decls.data(), Decls.size(), Out, Policy, Indentation);
294 Out << ";\n";
295 Decls.clear();
296
297}
298
299void DeclPrinter::Print(AccessSpecifier AS) {
300 const auto AccessSpelling = getAccessSpelling(AS);
301 if (AccessSpelling.empty())
302 llvm_unreachable("No access specifier!");
303 Out << AccessSpelling;
304}
305
306void DeclPrinter::PrintConstructorInitializers(CXXConstructorDecl *CDecl,
307 std::string &Proto) {
308 bool HasInitializerList = false;
309 for (const auto *BMInitializer : CDecl->inits()) {
310 if (BMInitializer->isInClassMemberInitializer())
311 continue;
312
313 if (!HasInitializerList) {
314 Proto += " : ";
315 Out << Proto;
316 Proto.clear();
317 HasInitializerList = true;
318 } else
319 Out << ", ";
320
321 if (BMInitializer->isAnyMemberInitializer()) {
322 FieldDecl *FD = BMInitializer->getAnyMember();
323 Out << *FD;
324 } else {
325 Out << QualType(BMInitializer->getBaseClass(), 0).getAsString(Policy);
326 }
327
328 Out << "(";
329 if (!BMInitializer->getInit()) {
330 // Nothing to print
331 } else {
332 Expr *Init = BMInitializer->getInit();
333 if (ExprWithCleanups *Tmp = dyn_cast<ExprWithCleanups>(Init))
334 Init = Tmp->getSubExpr();
335
336 Init = Init->IgnoreParens();
337
338 Expr *SimpleInit = nullptr;
339 Expr **Args = nullptr;
340 unsigned NumArgs = 0;
341 if (ParenListExpr *ParenList = dyn_cast<ParenListExpr>(Init)) {
342 Args = ParenList->getExprs();
343 NumArgs = ParenList->getNumExprs();
344 } else if (CXXConstructExpr *Construct =
345 dyn_cast<CXXConstructExpr>(Init)) {
346 Args = Construct->getArgs();
347 NumArgs = Construct->getNumArgs();
348 } else
349 SimpleInit = Init;
350
351 if (SimpleInit)
352 SimpleInit->printPretty(Out, nullptr, Policy, Indentation, "\n",
353 &Context);
354 else {
355 for (unsigned I = 0; I != NumArgs; ++I) {
356 assert(Args[I] != nullptr && "Expected non-null Expr");
357 if (isa<CXXDefaultArgExpr>(Args[I]))
358 break;
359
360 if (I)
361 Out << ", ";
362 Args[I]->printPretty(Out, nullptr, Policy, Indentation, "\n",
363 &Context);
364 }
365 }
366 }
367 Out << ")";
368 if (BMInitializer->isPackExpansion())
369 Out << "...";
370 }
371}
372
373//----------------------------------------------------------------------------
374// Common C declarations
375//----------------------------------------------------------------------------
376
377void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
378 if (Policy.TerseOutput)
379 return;
380
381 if (Indent)
382 Indentation += Policy.Indentation;
383
385 for (DeclContext::decl_iterator D = DC->decls_begin(), DEnd = DC->decls_end();
386 D != DEnd; ++D) {
387
388 // Don't print ObjCIvarDecls, as they are printed when visiting the
389 // containing ObjCInterfaceDecl.
390 if (isa<ObjCIvarDecl>(*D))
391 continue;
392
393 // Skip over implicit declarations in pretty-printing mode.
394 if (D->isImplicit())
395 continue;
396
397 // Don't print implicit specializations, as they are printed when visiting
398 // corresponding templates.
399 if (auto FD = dyn_cast<FunctionDecl>(*D))
400 if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation &&
401 !isa<ClassTemplateSpecializationDecl>(DC))
402 continue;
403
404 // The next bits of code handle stuff like "struct {int x;} a,b"; we're
405 // forced to merge the declarations because there's no other way to
406 // refer to the struct in question. When that struct is named instead, we
407 // also need to merge to avoid splitting off a stand-alone struct
408 // declaration that produces the warning ext_no_declarators in some
409 // contexts.
410 //
411 // This limited merging is safe without a bunch of other checks because it
412 // only merges declarations directly referring to the tag, not typedefs.
413 //
414 // Check whether the current declaration should be grouped with a previous
415 // non-free-standing tag declaration.
416 QualType CurDeclType = getDeclType(*D);
417 if (!Decls.empty() && !CurDeclType.isNull()) {
418 QualType BaseType = GetBaseType(CurDeclType);
419 if (!BaseType.isNull() && isa<ElaboratedType>(BaseType) &&
420 cast<ElaboratedType>(BaseType)->getOwnedTagDecl() == Decls[0]) {
421 Decls.push_back(*D);
422 continue;
423 }
424 }
425
426 // If we have a merged group waiting to be handled, handle it now.
427 if (!Decls.empty())
428 ProcessDeclGroup(Decls);
429
430 // If the current declaration is not a free standing declaration, save it
431 // so we can merge it with the subsequent declaration(s) using it.
432 if (isa<TagDecl>(*D) && !cast<TagDecl>(*D)->isFreeStanding()) {
433 Decls.push_back(*D);
434 continue;
435 }
436
437 if (isa<AccessSpecDecl>(*D)) {
438 Indentation -= Policy.Indentation;
439 this->Indent();
440 Print(D->getAccess());
441 Out << ":\n";
442 Indentation += Policy.Indentation;
443 continue;
444 }
445
446 this->Indent();
447 Visit(*D);
448
449 // FIXME: Need to be able to tell the DeclPrinter when
450 const char *Terminator = nullptr;
451 if (isa<OMPThreadPrivateDecl>(*D) || isa<OMPDeclareReductionDecl>(*D) ||
452 isa<OMPDeclareMapperDecl>(*D) || isa<OMPRequiresDecl>(*D) ||
453 isa<OMPAllocateDecl>(*D))
454 Terminator = nullptr;
455 else if (isa<ObjCMethodDecl>(*D) && cast<ObjCMethodDecl>(*D)->hasBody())
456 Terminator = nullptr;
457 else if (auto FD = dyn_cast<FunctionDecl>(*D)) {
458 if (FD->isThisDeclarationADefinition())
459 Terminator = nullptr;
460 else
461 Terminator = ";";
462 } else if (auto TD = dyn_cast<FunctionTemplateDecl>(*D)) {
463 if (TD->getTemplatedDecl()->isThisDeclarationADefinition())
464 Terminator = nullptr;
465 else
466 Terminator = ";";
470 Terminator = nullptr;
471 else if (isa<EnumConstantDecl>(*D)) {
473 ++Next;
474 if (Next != DEnd)
475 Terminator = ",";
476 } else
477 Terminator = ";";
478
479 if (Terminator)
480 Out << Terminator;
481 if (!Policy.TerseOutput &&
482 ((isa<FunctionDecl>(*D) &&
483 cast<FunctionDecl>(*D)->doesThisDeclarationHaveABody()) ||
484 (isa<FunctionTemplateDecl>(*D) &&
485 cast<FunctionTemplateDecl>(*D)->getTemplatedDecl()->doesThisDeclarationHaveABody())))
486 ; // StmtPrinter already added '\n' after CompoundStmt.
487 else
488 Out << "\n";
489
490 // Declare target attribute is special one, natural spelling for the pragma
491 // assumes "ending" construct so print it here.
492 if (D->hasAttr<OMPDeclareTargetDeclAttr>())
493 Out << "#pragma omp end declare target\n";
494 }
495
496 if (!Decls.empty())
497 ProcessDeclGroup(Decls);
498
499 if (Indent)
500 Indentation -= Policy.Indentation;
501}
502
503void DeclPrinter::VisitTranslationUnitDecl(TranslationUnitDecl *D) {
504 VisitDeclContext(D, false);
505}
506
507void DeclPrinter::VisitTypedefDecl(TypedefDecl *D) {
508 if (!Policy.SuppressSpecifiers) {
509 Out << "typedef ";
510
511 if (D->isModulePrivate())
512 Out << "__module_private__ ";
513 }
515 Ty.print(Out, Policy, D->getName(), Indentation);
516 prettyPrintAttributes(D);
517}
518
519void DeclPrinter::VisitTypeAliasDecl(TypeAliasDecl *D) {
520 Out << "using " << *D;
521 prettyPrintAttributes(D);
522 Out << " = " << D->getTypeSourceInfo()->getType().getAsString(Policy);
523}
524
525void DeclPrinter::VisitEnumDecl(EnumDecl *D) {
526 if (!Policy.SuppressSpecifiers && D->isModulePrivate())
527 Out << "__module_private__ ";
528 Out << "enum";
529 if (D->isScoped()) {
530 if (D->isScopedUsingClassTag())
531 Out << " class";
532 else
533 Out << " struct";
534 }
535
536 prettyPrintAttributes(D);
537
538 if (D->getDeclName())
539 Out << ' ' << D->getDeclName();
540
541 if (D->isFixed())
542 Out << " : " << D->getIntegerType().stream(Policy);
543
544 if (D->isCompleteDefinition()) {
545 Out << " {\n";
546 VisitDeclContext(D);
547 Indent() << "}";
548 }
549}
550
551void DeclPrinter::VisitRecordDecl(RecordDecl *D) {
552 if (!Policy.SuppressSpecifiers && D->isModulePrivate())
553 Out << "__module_private__ ";
554 Out << D->getKindName();
555
556 prettyPrintAttributes(D);
557
558 if (D->getIdentifier())
559 Out << ' ' << *D;
560
561 if (D->isCompleteDefinition()) {
562 Out << " {\n";
563 VisitDeclContext(D);
564 Indent() << "}";
565 }
566}
567
568void DeclPrinter::VisitEnumConstantDecl(EnumConstantDecl *D) {
569 Out << *D;
570 prettyPrintAttributes(D);
571 if (Expr *Init = D->getInitExpr()) {
572 Out << " = ";
573 Init->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
574 }
575}
576
577static void printExplicitSpecifier(ExplicitSpecifier ES, llvm::raw_ostream &Out,
578 PrintingPolicy &Policy, unsigned Indentation,
579 const ASTContext &Context) {
580 std::string Proto = "explicit";
581 llvm::raw_string_ostream EOut(Proto);
582 if (ES.getExpr()) {
583 EOut << "(";
584 ES.getExpr()->printPretty(EOut, nullptr, Policy, Indentation, "\n",
585 &Context);
586 EOut << ")";
587 }
588 EOut << " ";
589 EOut.flush();
590 Out << Proto;
591}
592
593void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
596 prettyPrintPragmas(D);
597
599 Out << "template<> ";
600 else if (!D->getDescribedFunctionTemplate()) {
601 for (unsigned I = 0, NumTemplateParams = D->getNumTemplateParameterLists();
602 I < NumTemplateParams; ++I)
603 printTemplateParameters(D->getTemplateParameterList(I));
604 }
605
606 CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
607 CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
608 CXXDeductionGuideDecl *GuideDecl = dyn_cast<CXXDeductionGuideDecl>(D);
609 if (!Policy.SuppressSpecifiers) {
610 switch (D->getStorageClass()) {
611 case SC_None: break;
612 case SC_Extern: Out << "extern "; break;
613 case SC_Static: Out << "static "; break;
614 case SC_PrivateExtern: Out << "__private_extern__ "; break;
615 case SC_Auto: case SC_Register:
616 llvm_unreachable("invalid for functions");
617 }
618
619 if (D->isInlineSpecified()) Out << "inline ";
620 if (D->isVirtualAsWritten()) Out << "virtual ";
621 if (D->isModulePrivate()) Out << "__module_private__ ";
623 Out << "constexpr ";
624 if (D->isConsteval()) Out << "consteval ";
626 if (ExplicitSpec.isSpecified())
627 printExplicitSpecifier(ExplicitSpec, Out, Policy, Indentation, Context);
628 }
629
630 PrintingPolicy SubPolicy(Policy);
631 SubPolicy.SuppressSpecifiers = false;
632 std::string Proto;
633
634 if (Policy.FullyQualifiedName) {
635 Proto += D->getQualifiedNameAsString();
636 } else {
637 llvm::raw_string_ostream OS(Proto);
638 if (!Policy.SuppressScope) {
639 if (const NestedNameSpecifier *NS = D->getQualifier()) {
640 NS->print(OS, Policy);
641 }
642 }
643 D->getNameInfo().printName(OS, Policy);
644 }
645
646 if (GuideDecl)
647 Proto = GuideDecl->getDeducedTemplate()->getDeclName().getAsString();
649 llvm::raw_string_ostream POut(Proto);
650 DeclPrinter TArgPrinter(POut, SubPolicy, Context, Indentation);
651 const auto *TArgAsWritten = D->getTemplateSpecializationArgsAsWritten();
652 if (TArgAsWritten && !Policy.PrintCanonicalTypes)
653 TArgPrinter.printTemplateArguments(TArgAsWritten->arguments(), nullptr);
654 else if (const TemplateArgumentList *TArgs =
656 TArgPrinter.printTemplateArguments(TArgs->asArray(), nullptr);
657 }
658
659 QualType Ty = D->getType();
660 while (const ParenType *PT = dyn_cast<ParenType>(Ty)) {
661 Proto = '(' + Proto + ')';
662 Ty = PT->getInnerType();
663 }
664
665 if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
666 const FunctionProtoType *FT = nullptr;
667 if (D->hasWrittenPrototype())
668 FT = dyn_cast<FunctionProtoType>(AFT);
669
670 Proto += "(";
671 if (FT) {
672 llvm::raw_string_ostream POut(Proto);
673 DeclPrinter ParamPrinter(POut, SubPolicy, Context, Indentation);
674 for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
675 if (i) POut << ", ";
676 ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
677 }
678
679 if (FT->isVariadic()) {
680 if (D->getNumParams()) POut << ", ";
681 POut << "...";
682 } else if (!D->getNumParams() && !Context.getLangOpts().CPlusPlus) {
683 // The function has a prototype, so it needs to retain the prototype
684 // in C.
685 POut << "void";
686 }
687 } else if (D->doesThisDeclarationHaveABody() && !D->hasPrototype()) {
688 for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
689 if (i)
690 Proto += ", ";
691 Proto += D->getParamDecl(i)->getNameAsString();
692 }
693 }
694
695 Proto += ")";
696
697 if (FT) {
698 if (FT->isConst())
699 Proto += " const";
700 if (FT->isVolatile())
701 Proto += " volatile";
702 if (FT->isRestrict())
703 Proto += " restrict";
704
705 switch (FT->getRefQualifier()) {
706 case RQ_None:
707 break;
708 case RQ_LValue:
709 Proto += " &";
710 break;
711 case RQ_RValue:
712 Proto += " &&";
713 break;
714 }
715 }
716
717 if (FT && FT->hasDynamicExceptionSpec()) {
718 Proto += " throw(";
719 if (FT->getExceptionSpecType() == EST_MSAny)
720 Proto += "...";
721 else
722 for (unsigned I = 0, N = FT->getNumExceptions(); I != N; ++I) {
723 if (I)
724 Proto += ", ";
725
726 Proto += FT->getExceptionType(I).getAsString(SubPolicy);
727 }
728 Proto += ")";
729 } else if (FT && isNoexceptExceptionSpec(FT->getExceptionSpecType())) {
730 Proto += " noexcept";
732 Proto += "(";
733 llvm::raw_string_ostream EOut(Proto);
734 FT->getNoexceptExpr()->printPretty(EOut, nullptr, SubPolicy,
735 Indentation, "\n", &Context);
736 EOut.flush();
737 Proto += ")";
738 }
739 }
740
741 if (CDecl) {
742 if (!Policy.TerseOutput)
743 PrintConstructorInitializers(CDecl, Proto);
744 } else if (!ConversionDecl && !isa<CXXDestructorDecl>(D)) {
745 if (FT && FT->hasTrailingReturn()) {
746 if (!GuideDecl)
747 Out << "auto ";
748 Out << Proto << " -> ";
749 Proto.clear();
750 }
751 AFT->getReturnType().print(Out, Policy, Proto);
752 Proto.clear();
753 }
754 Out << Proto;
755
756 if (Expr *TrailingRequiresClause = D->getTrailingRequiresClause()) {
757 Out << " requires ";
758 TrailingRequiresClause->printPretty(Out, nullptr, SubPolicy, Indentation,
759 "\n", &Context);
760 }
761 } else {
762 Ty.print(Out, Policy, Proto);
763 }
764
765 prettyPrintAttributes(D);
766
767 if (D->isPure())
768 Out << " = 0";
769 else if (D->isDeletedAsWritten())
770 Out << " = delete";
771 else if (D->isExplicitlyDefaulted())
772 Out << " = default";
773 else if (D->doesThisDeclarationHaveABody()) {
774 if (!Policy.TerseOutput) {
775 if (!D->hasPrototype() && D->getNumParams()) {
776 // This is a K&R function definition, so we need to print the
777 // parameters.
778 Out << '\n';
779 DeclPrinter ParamPrinter(Out, SubPolicy, Context, Indentation);
780 Indentation += Policy.Indentation;
781 for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
782 Indent();
783 ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
784 Out << ";\n";
785 }
786 Indentation -= Policy.Indentation;
787 }
788
789 if (D->getBody())
790 D->getBody()->printPrettyControlled(Out, nullptr, SubPolicy, Indentation, "\n",
791 &Context);
792 } else {
793 if (!Policy.TerseOutput && isa<CXXConstructorDecl>(*D))
794 Out << " {}";
795 }
796 }
797}
798
799void DeclPrinter::VisitFriendDecl(FriendDecl *D) {
800 if (TypeSourceInfo *TSI = D->getFriendType()) {
801 unsigned NumTPLists = D->getFriendTypeNumTemplateParameterLists();
802 for (unsigned i = 0; i < NumTPLists; ++i)
803 printTemplateParameters(D->getFriendTypeTemplateParameterList(i));
804 Out << "friend ";
805 Out << " " << TSI->getType().getAsString(Policy);
806 }
807 else if (FunctionDecl *FD =
808 dyn_cast<FunctionDecl>(D->getFriendDecl())) {
809 Out << "friend ";
810 VisitFunctionDecl(FD);
811 }
812 else if (FunctionTemplateDecl *FTD =
813 dyn_cast<FunctionTemplateDecl>(D->getFriendDecl())) {
814 Out << "friend ";
815 VisitFunctionTemplateDecl(FTD);
816 }
817 else if (ClassTemplateDecl *CTD =
818 dyn_cast<ClassTemplateDecl>(D->getFriendDecl())) {
819 Out << "friend ";
820 VisitRedeclarableTemplateDecl(CTD);
821 }
822}
823
824void DeclPrinter::VisitFieldDecl(FieldDecl *D) {
825 // FIXME: add printing of pragma attributes if required.
826 if (!Policy.SuppressSpecifiers && D->isMutable())
827 Out << "mutable ";
828 if (!Policy.SuppressSpecifiers && D->isModulePrivate())
829 Out << "__module_private__ ";
830
832 stream(Policy, D->getName(), Indentation);
833
834 if (D->isBitField()) {
835 Out << " : ";
836 D->getBitWidth()->printPretty(Out, nullptr, Policy, Indentation, "\n",
837 &Context);
838 }
839
840 Expr *Init = D->getInClassInitializer();
841 if (!Policy.SuppressInitializers && Init) {
843 Out << " ";
844 else
845 Out << " = ";
846 Init->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
847 }
848 prettyPrintAttributes(D);
849}
850
851void DeclPrinter::VisitLabelDecl(LabelDecl *D) {
852 Out << *D << ":";
853}
854
855void DeclPrinter::VisitVarDecl(VarDecl *D) {
856 prettyPrintPragmas(D);
857
859 ? D->getTypeSourceInfo()->getType()
861
862 if (!Policy.SuppressSpecifiers) {
864 if (SC != SC_None)
866
867 switch (D->getTSCSpec()) {
868 case TSCS_unspecified:
869 break;
870 case TSCS___thread:
871 Out << "__thread ";
872 break;
874 Out << "_Thread_local ";
875 break;
877 Out << "thread_local ";
878 break;
879 }
880
881 if (D->isModulePrivate())
882 Out << "__module_private__ ";
883
884 if (D->isConstexpr()) {
885 Out << "constexpr ";
887 }
888 }
889
890 printDeclType(T, (isa<ParmVarDecl>(D) && Policy.CleanUglifiedParameters &&
891 D->getIdentifier())
893 : D->getName());
894 Expr *Init = D->getInit();
895 if (!Policy.SuppressInitializers && Init) {
896 bool ImplicitInit = false;
897 if (D->isCXXForRangeDecl()) {
898 // FIXME: We should print the range expression instead.
899 ImplicitInit = true;
900 } else if (CXXConstructExpr *Construct =
901 dyn_cast<CXXConstructExpr>(Init->IgnoreImplicit())) {
902 if (D->getInitStyle() == VarDecl::CallInit &&
903 !Construct->isListInitialization()) {
904 ImplicitInit = Construct->getNumArgs() == 0 ||
905 Construct->getArg(0)->isDefaultArgument();
906 }
907 }
908 if (!ImplicitInit) {
909 if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init))
910 Out << "(";
911 else if (D->getInitStyle() == VarDecl::CInit) {
912 Out << " = ";
913 }
914 PrintingPolicy SubPolicy(Policy);
915 SubPolicy.SuppressSpecifiers = false;
916 SubPolicy.IncludeTagDefinition = false;
917 Init->printPretty(Out, nullptr, SubPolicy, Indentation, "\n", &Context);
918 if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init))
919 Out << ")";
920 }
921 }
922 prettyPrintAttributes(D);
923}
924
925void DeclPrinter::VisitParmVarDecl(ParmVarDecl *D) {
926 VisitVarDecl(D);
927}
928
929void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
930 Out << "__asm (";
931 D->getAsmString()->printPretty(Out, nullptr, Policy, Indentation, "\n",
932 &Context);
933 Out << ")";
934}
935
936void DeclPrinter::VisitTopLevelStmtDecl(TopLevelStmtDecl *D) {
937 assert(D->getStmt());
938 D->getStmt()->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
939}
940
941void DeclPrinter::VisitImportDecl(ImportDecl *D) {
942 Out << "@import " << D->getImportedModule()->getFullModuleName()
943 << ";\n";
944}
945
946void DeclPrinter::VisitStaticAssertDecl(StaticAssertDecl *D) {
947 Out << "static_assert(";
948 D->getAssertExpr()->printPretty(Out, nullptr, Policy, Indentation, "\n",
949 &Context);
950 if (StringLiteral *SL = D->getMessage()) {
951 Out << ", ";
952 SL->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
953 }
954 Out << ")";
955}
956
957//----------------------------------------------------------------------------
958// C++ declarations
959//----------------------------------------------------------------------------
960void DeclPrinter::VisitNamespaceDecl(NamespaceDecl *D) {
961 if (D->isInline())
962 Out << "inline ";
963
964 Out << "namespace ";
965 if (D->getDeclName())
966 Out << D->getDeclName() << ' ';
967 Out << "{\n";
968
969 VisitDeclContext(D);
970 Indent() << "}";
971}
972
973void DeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
974 Out << "using namespace ";
975 if (D->getQualifier())
976 D->getQualifier()->print(Out, Policy);
978}
979
980void DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
981 Out << "namespace " << *D << " = ";
982 if (D->getQualifier())
983 D->getQualifier()->print(Out, Policy);
984 Out << *D->getAliasedNamespace();
985}
986
987void DeclPrinter::VisitEmptyDecl(EmptyDecl *D) {
988 prettyPrintAttributes(D);
989}
990
991void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
992 // FIXME: add printing of pragma attributes if required.
993 if (!Policy.SuppressSpecifiers && D->isModulePrivate())
994 Out << "__module_private__ ";
995 Out << D->getKindName();
996
997 prettyPrintAttributes(D);
998
999 if (D->getIdentifier()) {
1000 Out << ' ' << *D;
1001
1002 if (auto S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1003 ArrayRef<TemplateArgument> Args = S->getTemplateArgs().asArray();
1004 if (!Policy.PrintCanonicalTypes)
1005 if (const auto* TSI = S->getTypeAsWritten())
1006 if (const auto *TST =
1007 dyn_cast<TemplateSpecializationType>(TSI->getType()))
1008 Args = TST->template_arguments();
1009 printTemplateArguments(
1010 Args, S->getSpecializedTemplate()->getTemplateParameters());
1011 }
1012 }
1013
1014 if (D->hasDefinition()) {
1015 if (D->hasAttr<FinalAttr>()) {
1016 Out << " final";
1017 }
1018 }
1019
1020 if (D->isCompleteDefinition()) {
1021 // Print the base classes
1022 if (D->getNumBases()) {
1023 Out << " : ";
1024 for (CXXRecordDecl::base_class_iterator Base = D->bases_begin(),
1025 BaseEnd = D->bases_end(); Base != BaseEnd; ++Base) {
1026 if (Base != D->bases_begin())
1027 Out << ", ";
1028
1029 if (Base->isVirtual())
1030 Out << "virtual ";
1031
1032 AccessSpecifier AS = Base->getAccessSpecifierAsWritten();
1033 if (AS != AS_none) {
1034 Print(AS);
1035 Out << " ";
1036 }
1037 Out << Base->getType().getAsString(Policy);
1038
1039 if (Base->isPackExpansion())
1040 Out << "...";
1041 }
1042 }
1043
1044 // Print the class definition
1045 // FIXME: Doesn't print access specifiers, e.g., "public:"
1046 if (Policy.TerseOutput) {
1047 Out << " {}";
1048 } else {
1049 Out << " {\n";
1050 VisitDeclContext(D);
1051 Indent() << "}";
1052 }
1053 }
1054}
1055
1056void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1057 const char *l;
1059 l = "C";
1060 else {
1061 assert(D->getLanguage() == LinkageSpecDecl::lang_cxx &&
1062 "unknown language in linkage specification");
1063 l = "C++";
1064 }
1065
1066 Out << "extern \"" << l << "\" ";
1067 if (D->hasBraces()) {
1068 Out << "{\n";
1069 VisitDeclContext(D);
1070 Indent() << "}";
1071 } else
1072 Visit(*D->decls_begin());
1073}
1074
1075void DeclPrinter::printTemplateParameters(const TemplateParameterList *Params,
1076 bool OmitTemplateKW) {
1077 assert(Params);
1078
1079 if (!OmitTemplateKW)
1080 Out << "template ";
1081 Out << '<';
1082
1083 bool NeedComma = false;
1084 for (const Decl *Param : *Params) {
1085 if (Param->isImplicit())
1086 continue;
1087
1088 if (NeedComma)
1089 Out << ", ";
1090 else
1091 NeedComma = true;
1092
1093 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
1094 VisitTemplateTypeParmDecl(TTP);
1095 } else if (auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
1096 VisitNonTypeTemplateParmDecl(NTTP);
1097 } else if (auto TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
1098 VisitTemplateDecl(TTPD);
1099 // FIXME: print the default argument, if present.
1100 }
1101 }
1102
1103 Out << '>';
1104 if (!OmitTemplateKW)
1105 Out << ' ';
1106}
1107
1108void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgument> Args,
1109 const TemplateParameterList *Params) {
1110 Out << "<";
1111 for (size_t I = 0, E = Args.size(); I < E; ++I) {
1112 if (I)
1113 Out << ", ";
1114 if (!Params)
1115 Args[I].print(Policy, Out, /*IncludeType*/ true);
1116 else
1117 Args[I].print(Policy, Out,
1119 Policy, Params, I));
1120 }
1121 Out << ">";
1122}
1123
1124void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
1125 const TemplateParameterList *Params) {
1126 Out << "<";
1127 for (size_t I = 0, E = Args.size(); I < E; ++I) {
1128 if (I)
1129 Out << ", ";
1130 if (!Params)
1131 Args[I].getArgument().print(Policy, Out, /*IncludeType*/ true);
1132 else
1133 Args[I].getArgument().print(
1134 Policy, Out,
1136 I));
1137 }
1138 Out << ">";
1139}
1140
1141void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
1142 printTemplateParameters(D->getTemplateParameters());
1143
1144 if (const TemplateTemplateParmDecl *TTP =
1145 dyn_cast<TemplateTemplateParmDecl>(D)) {
1146 Out << "class";
1147
1148 if (TTP->isParameterPack())
1149 Out << " ...";
1150 else if (TTP->getDeclName())
1151 Out << ' ';
1152
1153 if (TTP->getDeclName()) {
1154 if (Policy.CleanUglifiedParameters && TTP->getIdentifier())
1155 Out << TTP->getIdentifier()->deuglifiedName();
1156 else
1157 Out << TTP->getDeclName();
1158 }
1159 } else if (auto *TD = D->getTemplatedDecl())
1160 Visit(TD);
1161 else if (const auto *Concept = dyn_cast<ConceptDecl>(D)) {
1162 Out << "concept " << Concept->getName() << " = " ;
1163 Concept->getConstraintExpr()->printPretty(Out, nullptr, Policy, Indentation,
1164 "\n", &Context);
1165 }
1166}
1167
1168void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
1169 prettyPrintPragmas(D->getTemplatedDecl());
1170 // Print any leading template parameter lists.
1171 if (const FunctionDecl *FD = D->getTemplatedDecl()) {
1172 for (unsigned I = 0, NumTemplateParams = FD->getNumTemplateParameterLists();
1173 I < NumTemplateParams; ++I)
1174 printTemplateParameters(FD->getTemplateParameterList(I));
1175 }
1176 VisitRedeclarableTemplateDecl(D);
1177 // Declare target attribute is special one, natural spelling for the pragma
1178 // assumes "ending" construct so print it here.
1179 if (D->getTemplatedDecl()->hasAttr<OMPDeclareTargetDeclAttr>())
1180 Out << "#pragma omp end declare target\n";
1181
1182 // Never print "instantiations" for deduction guides (they don't really
1183 // have them).
1184 if (PrintInstantiation &&
1185 !isa<CXXDeductionGuideDecl>(D->getTemplatedDecl())) {
1186 FunctionDecl *PrevDecl = D->getTemplatedDecl();
1187 const FunctionDecl *Def;
1188 if (PrevDecl->isDefined(Def) && Def != PrevDecl)
1189 return;
1190 for (auto *I : D->specializations())
1191 if (I->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) {
1192 if (!PrevDecl->isThisDeclarationADefinition())
1193 Out << ";\n";
1194 Indent();
1195 prettyPrintPragmas(I);
1196 Visit(I);
1197 }
1198 }
1199}
1200
1201void DeclPrinter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
1202 VisitRedeclarableTemplateDecl(D);
1203
1204 if (PrintInstantiation) {
1205 for (auto *I : D->specializations())
1206 if (I->getSpecializationKind() == TSK_ImplicitInstantiation) {
1208 Out << ";";
1209 Out << "\n";
1210 Indent();
1211 Visit(I);
1212 }
1213 }
1214}
1215
1216void DeclPrinter::VisitClassTemplateSpecializationDecl(
1218 Out << "template<> ";
1219 VisitCXXRecordDecl(D);
1220}
1221
1222void DeclPrinter::VisitClassTemplatePartialSpecializationDecl(
1224 printTemplateParameters(D->getTemplateParameters());
1225 VisitCXXRecordDecl(D);
1226}
1227
1228//----------------------------------------------------------------------------
1229// Objective-C declarations
1230//----------------------------------------------------------------------------
1231
1232void DeclPrinter::PrintObjCMethodType(ASTContext &Ctx,
1234 QualType T) {
1235 Out << '(';
1237 Out << "in ";
1239 Out << "inout ";
1241 Out << "out ";
1243 Out << "bycopy ";
1245 Out << "byref ";
1247 Out << "oneway ";
1249 if (auto nullability = AttributedType::stripOuterNullability(T))
1250 Out << getNullabilitySpelling(*nullability, true) << ' ';
1251 }
1252
1253 Out << Ctx.getUnqualifiedObjCPointerType(T).getAsString(Policy);
1254 Out << ')';
1255}
1256
1257void DeclPrinter::PrintObjCTypeParams(ObjCTypeParamList *Params) {
1258 Out << "<";
1259 unsigned First = true;
1260 for (auto *Param : *Params) {
1261 if (First) {
1262 First = false;
1263 } else {
1264 Out << ", ";
1265 }
1266
1267 switch (Param->getVariance()) {
1269 break;
1270
1272 Out << "__covariant ";
1273 break;
1274
1276 Out << "__contravariant ";
1277 break;
1278 }
1279
1280 Out << Param->getDeclName();
1281
1282 if (Param->hasExplicitBound()) {
1283 Out << " : " << Param->getUnderlyingType().getAsString(Policy);
1284 }
1285 }
1286 Out << ">";
1287}
1288
1289void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) {
1290 if (OMD->isInstanceMethod())
1291 Out << "- ";
1292 else
1293 Out << "+ ";
1294 if (!OMD->getReturnType().isNull()) {
1295 PrintObjCMethodType(OMD->getASTContext(), OMD->getObjCDeclQualifier(),
1296 OMD->getReturnType());
1297 }
1298
1299 std::string name = OMD->getSelector().getAsString();
1300 std::string::size_type pos, lastPos = 0;
1301 for (const auto *PI : OMD->parameters()) {
1302 // FIXME: selector is missing here!
1303 pos = name.find_first_of(':', lastPos);
1304 if (lastPos != 0)
1305 Out << " ";
1306 Out << name.substr(lastPos, pos - lastPos) << ':';
1307 PrintObjCMethodType(OMD->getASTContext(),
1308 PI->getObjCDeclQualifier(),
1309 PI->getType());
1310 Out << *PI;
1311 lastPos = pos + 1;
1312 }
1313
1314 if (OMD->param_begin() == OMD->param_end())
1315 Out << name;
1316
1317 if (OMD->isVariadic())
1318 Out << ", ...";
1319
1320 prettyPrintAttributes(OMD);
1321
1322 if (OMD->getBody() && !Policy.TerseOutput) {
1323 Out << ' ';
1324 OMD->getBody()->printPretty(Out, nullptr, Policy, Indentation, "\n",
1325 &Context);
1326 }
1327 else if (Policy.PolishForDeclaration)
1328 Out << ';';
1329}
1330
1331void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) {
1332 std::string I = OID->getNameAsString();
1333 ObjCInterfaceDecl *SID = OID->getSuperClass();
1334
1335 bool eolnOut = false;
1336 if (SID)
1337 Out << "@implementation " << I << " : " << *SID;
1338 else
1339 Out << "@implementation " << I;
1340
1341 if (OID->ivar_size() > 0) {
1342 Out << "{\n";
1343 eolnOut = true;
1344 Indentation += Policy.Indentation;
1345 for (const auto *I : OID->ivars()) {
1346 Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
1347 getAsString(Policy) << ' ' << *I << ";\n";
1348 }
1349 Indentation -= Policy.Indentation;
1350 Out << "}\n";
1351 }
1352 else if (SID || (OID->decls_begin() != OID->decls_end())) {
1353 Out << "\n";
1354 eolnOut = true;
1355 }
1356 VisitDeclContext(OID, false);
1357 if (!eolnOut)
1358 Out << "\n";
1359 Out << "@end";
1360}
1361
1362void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
1363 std::string I = OID->getNameAsString();
1364 ObjCInterfaceDecl *SID = OID->getSuperClass();
1365
1366 if (!OID->isThisDeclarationADefinition()) {
1367 Out << "@class " << I;
1368
1369 if (auto TypeParams = OID->getTypeParamListAsWritten()) {
1370 PrintObjCTypeParams(TypeParams);
1371 }
1372
1373 Out << ";";
1374 return;
1375 }
1376 bool eolnOut = false;
1377 Out << "@interface " << I;
1378
1379 if (auto TypeParams = OID->getTypeParamListAsWritten()) {
1380 PrintObjCTypeParams(TypeParams);
1381 }
1382
1383 if (SID)
1384 Out << " : " << QualType(OID->getSuperClassType(), 0).getAsString(Policy);
1385
1386 // Protocols?
1387 const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();
1388 if (!Protocols.empty()) {
1389 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
1390 E = Protocols.end(); I != E; ++I)
1391 Out << (I == Protocols.begin() ? '<' : ',') << **I;
1392 Out << "> ";
1393 }
1394
1395 if (OID->ivar_size() > 0) {
1396 Out << "{\n";
1397 eolnOut = true;
1398 Indentation += Policy.Indentation;
1399 for (const auto *I : OID->ivars()) {
1400 Indent() << I->getASTContext()
1401 .getUnqualifiedObjCPointerType(I->getType())
1402 .getAsString(Policy) << ' ' << *I << ";\n";
1403 }
1404 Indentation -= Policy.Indentation;
1405 Out << "}\n";
1406 }
1407 else if (SID || (OID->decls_begin() != OID->decls_end())) {
1408 Out << "\n";
1409 eolnOut = true;
1410 }
1411
1412 VisitDeclContext(OID, false);
1413 if (!eolnOut)
1414 Out << "\n";
1415 Out << "@end";
1416 // FIXME: implement the rest...
1417}
1418
1419void DeclPrinter::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1420 if (!PID->isThisDeclarationADefinition()) {
1421 Out << "@protocol " << *PID << ";\n";
1422 return;
1423 }
1424 // Protocols?
1425 const ObjCList<ObjCProtocolDecl> &Protocols = PID->getReferencedProtocols();
1426 if (!Protocols.empty()) {
1427 Out << "@protocol " << *PID;
1428 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
1429 E = Protocols.end(); I != E; ++I)
1430 Out << (I == Protocols.begin() ? '<' : ',') << **I;
1431 Out << ">\n";
1432 } else
1433 Out << "@protocol " << *PID << '\n';
1434 VisitDeclContext(PID, false);
1435 Out << "@end";
1436}
1437
1438void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) {
1439 Out << "@implementation ";
1440 if (const auto *CID = PID->getClassInterface())
1441 Out << *CID;
1442 else
1443 Out << "<<error-type>>";
1444 Out << '(' << *PID << ")\n";
1445
1446 VisitDeclContext(PID, false);
1447 Out << "@end";
1448 // FIXME: implement the rest...
1449}
1450
1451void DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) {
1452 Out << "@interface ";
1453 if (const auto *CID = PID->getClassInterface())
1454 Out << *CID;
1455 else
1456 Out << "<<error-type>>";
1457 if (auto TypeParams = PID->getTypeParamList()) {
1458 PrintObjCTypeParams(TypeParams);
1459 }
1460 Out << "(" << *PID << ")\n";
1461 if (PID->ivar_size() > 0) {
1462 Out << "{\n";
1463 Indentation += Policy.Indentation;
1464 for (const auto *I : PID->ivars())
1465 Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
1466 getAsString(Policy) << ' ' << *I << ";\n";
1467 Indentation -= Policy.Indentation;
1468 Out << "}\n";
1469 }
1470
1471 VisitDeclContext(PID, false);
1472 Out << "@end";
1473
1474 // FIXME: implement the rest...
1475}
1476
1477void DeclPrinter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID) {
1478 Out << "@compatibility_alias " << *AID
1479 << ' ' << *AID->getClassInterface() << ";\n";
1480}
1481
1482/// PrintObjCPropertyDecl - print a property declaration.
1483///
1484/// Print attributes in the following order:
1485/// - class
1486/// - nonatomic | atomic
1487/// - assign | retain | strong | copy | weak | unsafe_unretained
1488/// - readwrite | readonly
1489/// - getter & setter
1490/// - nullability
1491void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
1493 Out << "@required\n";
1495 Out << "@optional\n";
1496
1497 QualType T = PDecl->getType();
1498
1499 Out << "@property";
1501 bool first = true;
1502 Out << "(";
1504 Out << (first ? "" : ", ") << "class";
1505 first = false;
1506 }
1507
1509 Out << (first ? "" : ", ") << "direct";
1510 first = false;
1511 }
1512
1513 if (PDecl->getPropertyAttributes() &
1515 Out << (first ? "" : ", ") << "nonatomic";
1516 first = false;
1517 }
1519 Out << (first ? "" : ", ") << "atomic";
1520 first = false;
1521 }
1522
1524 Out << (first ? "" : ", ") << "assign";
1525 first = false;
1526 }
1528 Out << (first ? "" : ", ") << "retain";
1529 first = false;
1530 }
1531
1533 Out << (first ? "" : ", ") << "strong";
1534 first = false;
1535 }
1537 Out << (first ? "" : ", ") << "copy";
1538 first = false;
1539 }
1541 Out << (first ? "" : ", ") << "weak";
1542 first = false;
1543 }
1544 if (PDecl->getPropertyAttributes() &
1546 Out << (first ? "" : ", ") << "unsafe_unretained";
1547 first = false;
1548 }
1549
1550 if (PDecl->getPropertyAttributes() &
1552 Out << (first ? "" : ", ") << "readwrite";
1553 first = false;
1554 }
1556 Out << (first ? "" : ", ") << "readonly";
1557 first = false;
1558 }
1559
1561 Out << (first ? "" : ", ") << "getter = ";
1562 PDecl->getGetterName().print(Out);
1563 first = false;
1564 }
1566 Out << (first ? "" : ", ") << "setter = ";
1567 PDecl->getSetterName().print(Out);
1568 first = false;
1569 }
1570
1571 if (PDecl->getPropertyAttributes() &
1573 if (auto nullability = AttributedType::stripOuterNullability(T)) {
1574 if (*nullability == NullabilityKind::Unspecified &&
1575 (PDecl->getPropertyAttributes() &
1577 Out << (first ? "" : ", ") << "null_resettable";
1578 } else {
1579 Out << (first ? "" : ", ")
1580 << getNullabilitySpelling(*nullability, true);
1581 }
1582 first = false;
1583 }
1584 }
1585
1586 (void) first; // Silence dead store warning due to idiomatic code.
1587 Out << ")";
1588 }
1589 std::string TypeStr = PDecl->getASTContext().getUnqualifiedObjCPointerType(T).
1590 getAsString(Policy);
1591 Out << ' ' << TypeStr;
1592 if (!StringRef(TypeStr).endswith("*"))
1593 Out << ' ';
1594 Out << *PDecl;
1595 if (Policy.PolishForDeclaration)
1596 Out << ';';
1597}
1598
1599void DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) {
1601 Out << "@synthesize ";
1602 else
1603 Out << "@dynamic ";
1604 Out << *PID->getPropertyDecl();
1605 if (PID->getPropertyIvarDecl())
1606 Out << '=' << *PID->getPropertyIvarDecl();
1607}
1608
1609void DeclPrinter::VisitUsingDecl(UsingDecl *D) {
1610 if (!D->isAccessDeclaration())
1611 Out << "using ";
1612 if (D->hasTypename())
1613 Out << "typename ";
1614 D->getQualifier()->print(Out, Policy);
1615
1616 // Use the correct record name when the using declaration is used for
1617 // inheriting constructors.
1618 for (const auto *Shadow : D->shadows()) {
1619 if (const auto *ConstructorShadow =
1620 dyn_cast<ConstructorUsingShadowDecl>(Shadow)) {
1621 assert(Shadow->getDeclContext() == ConstructorShadow->getDeclContext());
1622 Out << *ConstructorShadow->getNominatedBaseClass();
1623 return;
1624 }
1625 }
1626 Out << *D;
1627}
1628
1629void DeclPrinter::VisitUsingEnumDecl(UsingEnumDecl *D) {
1630 Out << "using enum " << D->getEnumDecl();
1631}
1632
1633void
1634DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
1635 Out << "using typename ";
1636 D->getQualifier()->print(Out, Policy);
1637 Out << D->getDeclName();
1638}
1639
1640void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1641 if (!D->isAccessDeclaration())
1642 Out << "using ";
1643 D->getQualifier()->print(Out, Policy);
1644 Out << D->getDeclName();
1645}
1646
1647void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) {
1648 // ignore
1649}
1650
1651void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
1652 Out << "#pragma omp threadprivate";
1653 if (!D->varlist_empty()) {
1655 E = D->varlist_end();
1656 I != E; ++I) {
1657 Out << (I == D->varlist_begin() ? '(' : ',');
1658 NamedDecl *ND = cast<DeclRefExpr>(*I)->getDecl();
1659 ND->printQualifiedName(Out);
1660 }
1661 Out << ")";
1662 }
1663}
1664
1665void DeclPrinter::VisitHLSLBufferDecl(HLSLBufferDecl *D) {
1666 if (D->isCBuffer())
1667 Out << "cbuffer ";
1668 else
1669 Out << "tbuffer ";
1670
1671 Out << *D;
1672
1673 prettyPrintAttributes(D);
1674
1675 Out << " {\n";
1676 VisitDeclContext(D);
1677 Indent() << "}";
1678}
1679
1680void DeclPrinter::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
1681 Out << "#pragma omp allocate";
1682 if (!D->varlist_empty()) {
1684 E = D->varlist_end();
1685 I != E; ++I) {
1686 Out << (I == D->varlist_begin() ? '(' : ',');
1687 NamedDecl *ND = cast<DeclRefExpr>(*I)->getDecl();
1688 ND->printQualifiedName(Out);
1689 }
1690 Out << ")";
1691 }
1692 if (!D->clauselist_empty()) {
1693 OMPClausePrinter Printer(Out, Policy);
1694 for (OMPClause *C : D->clauselists()) {
1695 Out << " ";
1696 Printer.Visit(C);
1697 }
1698 }
1699}
1700
1701void DeclPrinter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
1702 Out << "#pragma omp requires ";
1703 if (!D->clauselist_empty()) {
1704 OMPClausePrinter Printer(Out, Policy);
1705 for (auto I = D->clauselist_begin(), E = D->clauselist_end(); I != E; ++I)
1706 Printer.Visit(*I);
1707 }
1708}
1709
1710void DeclPrinter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
1711 if (!D->isInvalidDecl()) {
1712 Out << "#pragma omp declare reduction (";
1714 const char *OpName =
1716 assert(OpName && "not an overloaded operator");
1717 Out << OpName;
1718 } else {
1719 assert(D->getDeclName().isIdentifier());
1720 D->printName(Out, Policy);
1721 }
1722 Out << " : ";
1723 D->getType().print(Out, Policy);
1724 Out << " : ";
1725 D->getCombiner()->printPretty(Out, nullptr, Policy, 0, "\n", &Context);
1726 Out << ")";
1727 if (auto *Init = D->getInitializer()) {
1728 Out << " initializer(";
1729 switch (D->getInitializerKind()) {
1731 Out << "omp_priv(";
1732 break;
1734 Out << "omp_priv = ";
1735 break;
1737 break;
1738 }
1739 Init->printPretty(Out, nullptr, Policy, 0, "\n", &Context);
1741 Out << ")";
1742 Out << ")";
1743 }
1744 }
1745}
1746
1747void DeclPrinter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
1748 if (!D->isInvalidDecl()) {
1749 Out << "#pragma omp declare mapper (";
1750 D->printName(Out, Policy);
1751 Out << " : ";
1752 D->getType().print(Out, Policy);
1753 Out << " ";
1754 Out << D->getVarName();
1755 Out << ")";
1756 if (!D->clauselist_empty()) {
1757 OMPClausePrinter Printer(Out, Policy);
1758 for (auto *C : D->clauselists()) {
1759 Out << " ";
1760 Printer.Visit(C);
1761 }
1762 }
1763 }
1764}
1765
1766void DeclPrinter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
1767 D->getInit()->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
1768}
1769
1770void DeclPrinter::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *TTP) {
1771 if (const TypeConstraint *TC = TTP->getTypeConstraint())
1772 TC->print(Out, Policy);
1773 else if (TTP->wasDeclaredWithTypename())
1774 Out << "typename";
1775 else
1776 Out << "class";
1777
1778 if (TTP->isParameterPack())
1779 Out << " ...";
1780 else if (TTP->getDeclName())
1781 Out << ' ';
1782
1783 if (TTP->getDeclName()) {
1784 if (Policy.CleanUglifiedParameters && TTP->getIdentifier())
1785 Out << TTP->getIdentifier()->deuglifiedName();
1786 else
1787 Out << TTP->getDeclName();
1788 }
1789
1790 if (TTP->hasDefaultArgument()) {
1791 Out << " = ";
1792 Out << TTP->getDefaultArgument().getAsString(Policy);
1793 }
1794}
1795
1796void DeclPrinter::VisitNonTypeTemplateParmDecl(
1797 const NonTypeTemplateParmDecl *NTTP) {
1798 StringRef Name;
1799 if (IdentifierInfo *II = NTTP->getIdentifier())
1800 Name =
1801 Policy.CleanUglifiedParameters ? II->deuglifiedName() : II->getName();
1802 printDeclType(NTTP->getType(), Name, NTTP->isParameterPack());
1803
1804 if (NTTP->hasDefaultArgument()) {
1805 Out << " = ";
1806 NTTP->getDefaultArgument()->printPretty(Out, nullptr, Policy, Indentation,
1807 "\n", &Context);
1808 }
1809}
Defines the clang::ASTContext interface.
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
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.
Defines the clang::Module class, which describes a module in the source code.
SourceLocation Begin
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
Definition: ASTContext.h:182
const LangOptions & getLangOpts() const
Definition: ASTContext.h:761
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:683
QualType getUnqualifiedObjCPointerType(QualType type) const
getUnqualifiedObjCPointerType - Returns version of Objective-C pointer type with lifetime qualifier r...
Definition: ASTContext.h:2157
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:3043
static std::optional< NullabilityKind > stripOuterNullability(QualType &T)
Strip off the top-level nullability annotation on the given type, if it's there.
Definition: Type.cpp:4475
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: Type.h:5282
shadow_range shadows() const
Definition: DeclCXX.h:3437
Pointer to a block type.
Definition: Type.h:2880
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1518
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2491
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2818
Represents a C++ deduction guide declaration.
Definition: DeclCXX.h:1937
TemplateDecl * getDeducedTemplate() const
Get the template for which this guide performs deduction.
Definition: DeclCXX.h:1977
Represents a C++ struct/union/class.
Definition: DeclCXX.h:254
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:2154
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1402
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:1942
bool isTranslationUnit() const
Definition: DeclBase.h:2017
void dumpDeclContext() const
decl_iterator decls_end() const
Definition: DeclBase.h:2199
decl_iterator decls_begin() const
Definition: DeclBase.cpp:1498
A simple visitor class that helps create declaration visitors.
Definition: DeclVisitor.h:67
Decl - This represents one declaration (or definition), e.g.
Definition: DeclBase.h:83
bool hasAttrs() const
Definition: DeclBase.h:502
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:429
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:576
ObjCDeclQualifier
ObjCDeclQualifier - 'Qualifiers' written next to the return and parameter types in method declaration...
Definition: DeclBase.h:195
@ OBJC_TQ_Byref
Definition: DeclBase.h:201
@ OBJC_TQ_Oneway
Definition: DeclBase.h:202
@ OBJC_TQ_Bycopy
Definition: DeclBase.h:200
@ OBJC_TQ_CSNullability
The nullability qualifier is set when the nullability of the result or parameter was expressed via a ...
Definition: DeclBase.h:207
@ OBJC_TQ_Inout
Definition: DeclBase.h:198
bool isInvalidDecl() const
Definition: DeclBase.h:571
static void printGroup(Decl **Begin, unsigned NumDecls, raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation=0)
AccessSpecifier getAccess() const
Definition: DeclBase.h:491
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
AttrVec & getAttrs()
Definition: DeclBase.h:508
bool hasAttr() const
Definition: DeclBase.h:560
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.
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
Definition: Decl.h:823
TemplateParameterList * getTemplateParameterList(unsigned index) const
Definition: Decl.h:857
unsigned getNumTemplateParameterLists() const
Definition: Decl.h:853
Expr * getTrailingRequiresClause()
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
Definition: Decl.h:841
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:794
Represents an empty-declaration.
Definition: Decl.h:4786
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:3174
const Expr * getInitExpr() const
Definition: Decl.h:3193
Represents an enum.
Definition: Decl.h:3734
bool isScoped() const
Returns true if this is a C++11 scoped enumeration.
Definition: Decl.h:3939
bool isScopedUsingClassTag() const
Returns true if this is a C++11 scoped enumeration.
Definition: Decl.h:3942
bool isFixed() const
Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...
Definition: Decl.h:3948
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
Definition: Decl.h:3894
Store information needed for an explicit specifier.
Definition: DeclCXX.h:1882
const Expr * getExpr() const
Definition: DeclCXX.h:1891
static ExplicitSpecifier getFromDecl(FunctionDecl *Function)
Definition: DeclCXX.cpp:2105
bool isSpecified() const
Determine if the declaration had an explicit specifier of any kind.
Definition: DeclCXX.h:1895
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition: ExprCXX.h:3420
This represents one expression.
Definition: Expr.h:110
bool isDefaultArgument() const
Determine whether this expression is a default function argument.
Definition: Expr.cpp:3150
Represents a member of a struct/union/class.
Definition: Decl.h:2945
bool isMutable() const
Determines whether this field is mutable (C++ only).
Definition: Decl.h:3030
Expr * getInClassInitializer() const
Get the C++11 default member initializer for this member, or null if one has not been set.
Definition: Decl.cpp:4376
bool isBitField() const
Determines whether this field is a bitfield.
Definition: Decl.h:3033
InClassInitStyle getInClassInitStyle() const
Get the kind of (C++11) default member initializer that this field has.
Definition: Decl.h:3093
Expr * getBitWidth() const
Definition: Decl.h:3044
const StringLiteral * getAsmString() const
Definition: Decl.h:4309
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
Definition: DeclFriend.h:54
unsigned getFriendTypeNumTemplateParameterLists() const
Definition: DeclFriend.h:125
TemplateParameterList * getFriendTypeTemplateParameterList(unsigned N) const
Definition: DeclFriend.h:129
NamedDecl * getFriendDecl() const
If this friend declaration doesn't name a type, return the inner declaration.
Definition: DeclFriend.h:136
TypeSourceInfo * getFriendType() const
If this friend declaration names an (untemplated but possibly dependent) type, return the type; other...
Definition: DeclFriend.h:121
Represents a function declaration or definition.
Definition: Decl.h:1917
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:2609
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition: Decl.cpp:3138
bool isPure() const
Whether this virtual function is pure, i.e.
Definition: Decl.h:2255
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition: Decl.cpp:3878
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition: Decl.h:2216
bool isExplicitlyDefaulted() const
Whether this function is explicitly defaulted.
Definition: Decl.h:2284
bool hasWrittenPrototype() const
Whether this function has a written prototype.
Definition: Decl.h:2343
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
Definition: Decl.h:2338
bool doesThisDeclarationHaveABody() const
Returns whether this specific declaration of the function has a body.
Definition: Decl.h:2228
bool isConstexprSpecified() const
Definition: Decl.h:2374
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Definition: Decl.cpp:4008
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Definition: Decl.h:2683
bool isDeletedAsWritten() const
Definition: Decl.h:2424
bool isConsteval() const
Definition: Decl.h:2377
bool isVirtualAsWritten() const
Whether this function is marked as virtual explicitly.
Definition: Decl.h:2246
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
Definition: Decl.h:2799
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition: Decl.cpp:3542
DeclarationNameInfo getNameInfo() const
Definition: Decl.h:2115
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:3105
bool isInlineSpecified() const
Determine whether the "inline" keyword was specified for this function.
Definition: Decl.h:2694
const ASTTemplateArgumentListInfo * getTemplateSpecializationArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
Definition: Decl.cpp:4018
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4056
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition: Type.h:4286
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition: Type.h:4399
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition: Type.h:4337
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition: Type.h:4329
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
Definition: Type.h:4295
bool isVariadic() const
Whether this function prototype is variadic.
Definition: Type.h:4383
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition: Type.h:4344
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition: Type.h:4409
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: Type.h:3709
bool isConst() const
Definition: Type.h:3992
bool isRestrict() const
Definition: Type.h:3994
bool isVolatile() const
Definition: Type.h:3993
HLSLBufferDecl - Represent a cbuffer or tbuffer declaration.
Definition: Decl.h:4801
bool isCBuffer() const
Definition: Decl.h:4829
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:4660
Module * getImportedModule() const
Retrieve the module that was imported by the import declaration.
Definition: Decl.h:4718
Represents the declaration of a label.
Definition: Decl.h:494
Represents a linkage specification.
Definition: DeclCXX.h:2884
LanguageIDs getLanguage() const
Return the language specified by this linkage specification.
Definition: DeclCXX.h:2913
bool hasBraces() const
Determines whether this linkage specification had braces in its syntactic form.
Definition: DeclCXX.h:2922
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:241
This represents a decl that may have a name.
Definition: Decl.h:247
bool isModulePrivate() const
Whether this declaration was marked as being private to the module in which it was defined.
Definition: DeclBase.h:625
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:268
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:274
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:313
std::string getQualifiedNameAsString() const
Definition: Decl.cpp:1646
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:290
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:1653
virtual void printName(raw_ostream &OS, const PrintingPolicy &Policy) const
Pretty-print the unqualified name of this declaration.
Definition: Decl.cpp:1638
Represents a C++ namespace alias.
Definition: DeclCXX.h:3074
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of the namespace.
Definition: DeclCXX.h:3141
NamedDecl * getAliasedNamespace() const
Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...
Definition: DeclCXX.h:3169
Represent a C++ namespace.
Definition: Decl.h:542
bool isInline() const
Returns true if this is an inline namespace declaration.
Definition: Decl.h:605
Represents a C++ nested name specifier, such as "\::std::vector<int>::".
void print(raw_ostream &OS, const PrintingPolicy &Policy, bool ResolveTemplateArguments=false) 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 isParameterPack() const
Whether this parameter is a non-type template parameter pack.
Expr * getDefaultArgument() const
Retrieve the default argument, if any.
This represents '#pragma omp allocate ...' directive.
Definition: DeclOpenMP.h:473
bool varlist_empty() const
Definition: DeclOpenMP.h:511
bool clauselist_empty() const
Definition: DeclOpenMP.h:513
varlist_iterator varlist_begin()
Definition: DeclOpenMP.h:521
MutableArrayRef< Expr * >::iterator varlist_iterator
Definition: DeclOpenMP.h:501
clauselist_range clauselists()
Definition: DeclOpenMP.h:526
varlist_iterator varlist_end()
Definition: DeclOpenMP.h:522
Pseudo declaration for capturing expressions.
Definition: DeclOpenMP.h:383
This is a basic class for representing single OpenMP clause.
Definition: OpenMPClause.h:55
This represents '#pragma omp declare mapper ...' directive.
Definition: DeclOpenMP.h:287
clauselist_range clauselists()
Definition: DeclOpenMP.h:333
DeclarationName getVarName()
Get the name of the variable declared in the mapper.
Definition: DeclOpenMP.h:359
bool clauselist_empty() const
Definition: DeclOpenMP.h:331
This represents '#pragma omp declare reduction ...' directive.
Definition: DeclOpenMP.h:171
Expr * getInitializer()
Get initializer expression (if specified) of the declare reduction construct.
Definition: DeclOpenMP.h:239
Expr * getCombiner()
Get combiner expression of the declare reduction construct.
Definition: DeclOpenMP.h:221
InitKind getInitializerKind() const
Get initializer kind.
Definition: DeclOpenMP.h:242
This represents '#pragma omp requires...' directive.
Definition: DeclOpenMP.h:416
clauselist_iterator clauselist_begin()
Definition: DeclOpenMP.h:447
bool clauselist_empty() const
Definition: DeclOpenMP.h:439
clauselist_iterator clauselist_end()
Definition: DeclOpenMP.h:448
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:2312
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.h:2357
ObjCTypeParamList * getTypeParamList() const
Retrieve the type parameter list associated with this category or extension.
Definition: DeclObjC.h:2362
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
Definition: DeclObjC.h:2531
ObjCCompatibleAliasDecl - Represents alias of a class.
Definition: DeclObjC.h:2759
const ObjCInterfaceDecl * getClassInterface() const
Definition: DeclObjC.h:2777
const ObjCInterfaceDecl * getClassInterface() const
Definition: DeclObjC.h:2472
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
Definition: DeclObjC.h:2584
std::string getNameAsString() const
Get the name of the class associated with this interface.
Definition: DeclObjC.h:2713
ivar_range ivars() const
Definition: DeclObjC.h:2733
unsigned ivar_size() const
Definition: DeclObjC.h:2743
const ObjCInterfaceDecl * getSuperClass() const
Definition: DeclObjC.h:2719
Represents an ObjC class declaration.
Definition: DeclObjC.h:1147
unsigned ivar_size() const
Definition: DeclObjC.h:1457
ivar_range ivars() const
Definition: DeclObjC.h:1439
ObjCTypeParamList * getTypeParamListAsWritten() const
Retrieve the type parameters written on this particular declaration of the class.
Definition: DeclObjC.h:1292
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
Definition: DeclObjC.h:1511
const ObjCProtocolList & getReferencedProtocols() const
Definition: DeclObjC.h:1322
const ObjCObjectType * getSuperClassType() const
Retrieve the superclass type.
Definition: DeclObjC.h:1553
ObjCInterfaceDecl * getSuperClass() const
Definition: DeclObjC.cpp:351
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:138
ObjCDeclQualifier getObjCDeclQualifier() const
Definition: DeclObjC.h:248
ArrayRef< ParmVarDecl * > parameters() const
Definition: DeclObjC.h:375
param_const_iterator param_end() const
Definition: DeclObjC.h:360
param_const_iterator param_begin() const
Definition: DeclObjC.h:356
bool isVariadic() const
Definition: DeclObjC.h:433
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
Definition: DeclObjC.cpp:909
Selector getSelector() const
Definition: DeclObjC.h:329
bool isInstanceMethod() const
Definition: DeclObjC.h:428
QualType getReturnType() const
Definition: DeclObjC.h:331
Represents a pointer to an Objective C object.
Definition: Type.h:6312
Represents one property declaration in an Objective-C interface.
Definition: DeclObjC.h:729
Selector getSetterName() const
Definition: DeclObjC.h:886
QualType getType() const
Definition: DeclObjC.h:797
Selector getGetterName() const
Definition: DeclObjC.h:878
ObjCPropertyAttribute::Kind getPropertyAttributes() const
Definition: DeclObjC.h:808
PropertyControl getPropertyImplementation() const
Definition: DeclObjC.h:905
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
Definition: DeclObjC.h:2789
ObjCIvarDecl * getPropertyIvarDecl() const
Definition: DeclObjC.h:2862
Kind getPropertyImplementation() const
Definition: DeclObjC.h:2858
ObjCPropertyDecl * getPropertyDecl() const
Definition: DeclObjC.h:2853
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2069
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
Definition: DeclObjC.h:2244
const ObjCProtocolList & getReferencedProtocols() const
Definition: DeclObjC.h:2136
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
Definition: DeclObjC.h:658
Represents a pack expansion of types.
Definition: Type.h:5873
Sugar for parentheses used when specifying types.
Definition: Type.h:2774
Represents a parameter to a function.
Definition: Decl.h:1722
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:2800
A (possibly-)qualified type.
Definition: Type.h:736
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:803
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
void removeLocalConst()
Definition: Type.h:6771
StreamedQualTypeHelper stream(const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:1147
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:1091
Represents a struct/union/class.
Definition: Decl.h:4012
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:2911
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:").
Represents a C++11 static_assert declaration.
Definition: DeclCXX.h:4011
StringLiteral * getMessage()
Definition: DeclCXX.h:4037
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:1780
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3454
StringRef getKindName() const
Definition: Decl.h:3645
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3557
A template argument list.
Definition: DeclTemplate.h:240
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:409
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:441
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:428
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
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.
Declaration of a template type parameter.
bool wasDeclaredWithTypename() const
Whether this template type parameter was declared with the 'typename' keyword.
QualType 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 isParameterPack() const
Returns whether this is a parameter pack.
A declaration that models statements at global scope.
Definition: Decl.h:4322
The top declaration context.
Definition: Decl.h:82
Represents the declaration of a typedef-name via a C++11 alias-declaration.
Definition: Decl.h:3426
A container of type source information.
Definition: Type.h:6635
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:6646
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:631
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
Definition: Type.cpp:2947
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:7430
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition: Decl.h:3406
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3304
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:3354
Represents a dependent using declaration which was marked with typename.
Definition: DeclCXX.h:3912
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name.
Definition: DeclCXX.h:3949
Represents a dependent using declaration which was not marked with typename.
Definition: DeclCXX.h:3815
bool isAccessDeclaration() const
Return true if it is a C++03 access declaration (no 'using').
Definition: DeclCXX.h:3852
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name.
Definition: DeclCXX.h:3859
Represents a C++ using-declaration.
Definition: DeclCXX.h:3466
bool hasTypename() const
Return true if the using declaration has 'typename'.
Definition: DeclCXX.h:3515
bool isAccessDeclaration() const
Return true if it is a C++03 access declaration (no 'using').
Definition: DeclCXX.h:3512
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name.
Definition: DeclCXX.h:3503
Represents C++ using-directive.
Definition: DeclCXX.h:2969
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of the namespace.
Definition: DeclCXX.h:3018
NamedDecl * getNominatedNamespaceAsWritten()
Definition: DeclCXX.h:3022
Represents a C++ using-enum-declaration.
Definition: DeclCXX.h:3666
EnumDecl * getEnumDecl() const
Definition: DeclCXX.h:3710
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition: DeclCXX.h:3274
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:701
QualType getType() const
Definition: Decl.h:712
Represents a variable declaration or definition.
Definition: Decl.h:913
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
Definition: Decl.h:1519
InitializationStyle getInitStyle() const
The style of initialization for this declaration.
Definition: Decl.h:1416
static const char * getStorageClassSpecifierString(StorageClass SC)
Return the string used to specify the storage class SC.
Definition: Decl.cpp:2066
@ CInit
C-style initialization with assignment.
Definition: Decl.h:918
@ CallInit
Call-style initialization (C++98)
Definition: Decl.h:921
bool isCXXForRangeDecl() const
Determine whether this variable is the for-range-declaration in a C++0x for-range statement.
Definition: Decl.h:1472
ThreadStorageClassSpecifier getTSCSpec() const
Definition: Decl.h:1134
const Expr * getInit() const
Definition: Decl.h:1325
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Definition: Decl.h:1125
Represents a GCC generic vector type.
Definition: Type.h:3389
@ kind_nullability
Indicates that the nullability of the type was spelled with a property attribute rather than a type q...
RangeSelector name(std::string ID)
Given a node with a "name", (like NamedDecl, DeclRefExpr, CxxCtorInitializer, and TypeLoc) selects th...
llvm::StringRef getAccessSpelling(AccessSpecifier AS)
Definition: Specifiers.h:388
@ Unspecified
Whether values of this type can be null is (explicitly) unspecified.
@ ICIS_ListInit
Direct list-initialization.
Definition: Specifiers.h:265
@ RQ_None
No ref-qualifier was provided.
Definition: Type.h:1521
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition: Type.h:1524
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition: Type.h:1527
StorageClass
Storage classes.
Definition: Specifiers.h:239
@ SC_Auto
Definition: Specifiers.h:247
@ SC_PrivateExtern
Definition: Specifiers.h:244
@ SC_Extern
Definition: Specifiers.h:242
@ SC_Register
Definition: Specifiers.h:248
@ SC_Static
Definition: Specifiers.h:243
@ SC_None
Definition: Specifiers.h:241
@ TSCS_thread_local
C++11 thread_local.
Definition: Specifiers.h:232
@ TSCS_unspecified
Definition: Specifiers.h:227
@ TSCS__Thread_local
C11 _Thread_local.
Definition: Specifiers.h:235
@ TSCS___thread
GNU __thread.
Definition: Specifiers.h:229
@ C
Languages that the frontend can parse and compile.
llvm::StringRef getNullabilitySpelling(NullabilityKind kind, bool isContextSensitive=false)
Retrieve the spelling of the given nullability kind.
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
llvm::StringRef getAsString(SyncScope S)
Definition: SyncScope.h:55
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
Definition: Specifiers.h:185
@ Invariant
The parameter is invariant: must match exactly.
@ Contravariant
The parameter is contravariant, e.g., X<T> is a subtype of X when the type parameter is covariant and...
@ Covariant
The parameter is covariant, e.g., X<T> is a subtype of X when the type parameter is covariant and T i...
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
@ EST_MSAny
Microsoft throw(...) extension.
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
Definition: Specifiers.h:114
@ AS_none
Definition: Specifiers.h:118
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.
Definition: PrettyPrinter.h:57
unsigned FullyQualifiedName
When true, print the fully qualified name of function declarations.
unsigned PrintCanonicalTypes
Whether to print types as written or canonically.
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.
Definition: PrettyPrinter.h:92
unsigned SuppressInitializers
Suppress printing of variable initializers.
unsigned IncludeTagDefinition
When true, include the body of a tag definition.
unsigned TerseOutput
Provide a 'terse' output.