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