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