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 EOut.flush();
633 Out << Proto;
634}
635
637 QualType T,
638 llvm::raw_ostream &Out) {
639 StringRef prefix = T->isClassType() ? "class "
640 : T->isStructureType() ? "struct "
641 : T->isUnionType() ? "union "
642 : "";
643 Out << prefix;
644}
645
646void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
647 if (!D->getDescribedFunctionTemplate() &&
648 !D->isFunctionTemplateSpecialization()) {
649 prettyPrintPragmas(D);
650 prettyPrintAttributes(D, AttrPosAsWritten::Left);
651 }
652
653 if (D->isFunctionTemplateSpecialization())
654 Out << "template<> ";
655 else if (!D->getDescribedFunctionTemplate()) {
656 for (unsigned I = 0, NumTemplateParams = D->getNumTemplateParameterLists();
657 I < NumTemplateParams; ++I)
658 printTemplateParameters(D->getTemplateParameterList(I));
659 }
660
661 CXXConstructorDecl *CDecl = dyn_cast<CXXConstructorDecl>(D);
662 CXXConversionDecl *ConversionDecl = dyn_cast<CXXConversionDecl>(D);
663 CXXDeductionGuideDecl *GuideDecl = dyn_cast<CXXDeductionGuideDecl>(D);
664 if (!Policy.SuppressSpecifiers) {
665 switch (D->getStorageClass()) {
666 case SC_None: break;
667 case SC_Extern: Out << "extern "; break;
668 case SC_Static: Out << "static "; break;
669 case SC_PrivateExtern: Out << "__private_extern__ "; break;
670 case SC_Auto: case SC_Register:
671 llvm_unreachable("invalid for functions");
672 }
673
674 if (D->isInlineSpecified()) Out << "inline ";
675 if (D->isVirtualAsWritten()) Out << "virtual ";
676 if (D->isModulePrivate()) Out << "__module_private__ ";
677 if (D->isConstexprSpecified() && !D->isExplicitlyDefaulted())
678 Out << "constexpr ";
679 if (D->isConsteval()) Out << "consteval ";
680 else if (D->isImmediateFunction())
681 Out << "immediate ";
683 if (ExplicitSpec.isSpecified())
684 printExplicitSpecifier(ExplicitSpec, Out, Policy, Indentation, Context);
685 }
686
687 PrintingPolicy SubPolicy(Policy);
688 SubPolicy.SuppressSpecifiers = false;
689 std::string Proto;
690
691 if (Policy.FullyQualifiedName) {
692 Proto += D->getQualifiedNameAsString();
693 } else {
694 llvm::raw_string_ostream OS(Proto);
695 if (!Policy.SuppressScope) {
696 if (const NestedNameSpecifier *NS = D->getQualifier()) {
697 NS->print(OS, Policy);
698 }
699 }
700 D->getNameInfo().printName(OS, Policy);
701 }
702
703 if (GuideDecl)
704 Proto = GuideDecl->getDeducedTemplate()->getDeclName().getAsString();
705 if (D->isFunctionTemplateSpecialization()) {
706 llvm::raw_string_ostream POut(Proto);
707 DeclPrinter TArgPrinter(POut, SubPolicy, Context, Indentation);
708 const auto *TArgAsWritten = D->getTemplateSpecializationArgsAsWritten();
709 if (TArgAsWritten && !Policy.PrintCanonicalTypes)
710 TArgPrinter.printTemplateArguments(TArgAsWritten->arguments(), nullptr);
711 else if (const TemplateArgumentList *TArgs =
712 D->getTemplateSpecializationArgs())
713 TArgPrinter.printTemplateArguments(TArgs->asArray(), nullptr);
714 }
715
716 QualType Ty = D->getType();
717 while (const ParenType *PT = dyn_cast<ParenType>(Ty)) {
718 Proto = '(' + Proto + ')';
719 Ty = PT->getInnerType();
720 }
721
722 if (const FunctionType *AFT = Ty->getAs<FunctionType>()) {
723 const FunctionProtoType *FT = nullptr;
724 if (D->hasWrittenPrototype())
725 FT = dyn_cast<FunctionProtoType>(AFT);
726
727 Proto += "(";
728 if (FT) {
729 llvm::raw_string_ostream POut(Proto);
730 DeclPrinter ParamPrinter(POut, SubPolicy, Context, Indentation);
731 for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
732 if (i) POut << ", ";
733 ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
734 }
735
736 if (FT->isVariadic()) {
737 if (D->getNumParams()) POut << ", ";
738 POut << "...";
739 } else if (!D->getNumParams() && !Context.getLangOpts().CPlusPlus) {
740 // The function has a prototype, so it needs to retain the prototype
741 // in C.
742 POut << "void";
743 }
744 } else if (D->doesThisDeclarationHaveABody() && !D->hasPrototype()) {
745 for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
746 if (i)
747 Proto += ", ";
748 Proto += D->getParamDecl(i)->getNameAsString();
749 }
750 }
751
752 Proto += ")";
753
754 if (FT) {
755 if (FT->isConst())
756 Proto += " const";
757 if (FT->isVolatile())
758 Proto += " volatile";
759 if (FT->isRestrict())
760 Proto += " restrict";
761
762 switch (FT->getRefQualifier()) {
763 case RQ_None:
764 break;
765 case RQ_LValue:
766 Proto += " &";
767 break;
768 case RQ_RValue:
769 Proto += " &&";
770 break;
771 }
772 }
773
774 if (FT && FT->hasDynamicExceptionSpec()) {
775 Proto += " throw(";
776 if (FT->getExceptionSpecType() == EST_MSAny)
777 Proto += "...";
778 else
779 for (unsigned I = 0, N = FT->getNumExceptions(); I != N; ++I) {
780 if (I)
781 Proto += ", ";
782
783 Proto += FT->getExceptionType(I).getAsString(SubPolicy);
784 }
785 Proto += ")";
786 } else if (FT && isNoexceptExceptionSpec(FT->getExceptionSpecType())) {
787 Proto += " noexcept";
789 Proto += "(";
790 llvm::raw_string_ostream EOut(Proto);
791 FT->getNoexceptExpr()->printPretty(EOut, nullptr, SubPolicy,
792 Indentation, "\n", &Context);
793 EOut.flush();
794 Proto += ")";
795 }
796 }
797
798 if (CDecl) {
799 if (!Policy.TerseOutput)
800 PrintConstructorInitializers(CDecl, Proto);
801 } else if (!ConversionDecl && !isa<CXXDestructorDecl>(D)) {
802 if (FT && FT->hasTrailingReturn()) {
803 if (!GuideDecl)
804 Out << "auto ";
805 Out << Proto << " -> ";
806 Proto.clear();
807 }
808 if (!Policy.SuppressTagKeyword && Policy.SuppressScope &&
810 MaybePrintTagKeywordIfSupressingScopes(Policy, AFT->getReturnType(),
811 Out);
812 AFT->getReturnType().print(Out, Policy, Proto);
813 Proto.clear();
814 }
815 Out << Proto;
816
817 if (Expr *TrailingRequiresClause = D->getTrailingRequiresClause()) {
818 Out << " requires ";
819 TrailingRequiresClause->printPretty(Out, nullptr, SubPolicy, Indentation,
820 "\n", &Context);
821 }
822 } else {
823 Ty.print(Out, Policy, Proto);
824 }
825
826 prettyPrintAttributes(D, AttrPosAsWritten::Right);
827
828 if (D->isPureVirtual())
829 Out << " = 0";
830 else if (D->isDeletedAsWritten()) {
831 Out << " = delete";
832 if (const StringLiteral *M = D->getDeletedMessage()) {
833 Out << "(";
834 M->outputString(Out);
835 Out << ")";
836 }
837 } else if (D->isExplicitlyDefaulted())
838 Out << " = default";
839 else if (D->doesThisDeclarationHaveABody()) {
840 if (!Policy.TerseOutput) {
841 if (!D->hasPrototype() && D->getNumParams()) {
842 // This is a K&R function definition, so we need to print the
843 // parameters.
844 Out << '\n';
845 DeclPrinter ParamPrinter(Out, SubPolicy, Context, Indentation);
846 Indentation += Policy.Indentation;
847 for (unsigned i = 0, e = D->getNumParams(); i != e; ++i) {
848 Indent();
849 ParamPrinter.VisitParmVarDecl(D->getParamDecl(i));
850 Out << ";\n";
851 }
852 Indentation -= Policy.Indentation;
853 }
854
855 if (D->getBody())
856 D->getBody()->printPrettyControlled(Out, nullptr, SubPolicy, Indentation, "\n",
857 &Context);
858 } else {
859 if (!Policy.TerseOutput && isa<CXXConstructorDecl>(*D))
860 Out << " {}";
861 }
862 }
863}
864
865void DeclPrinter::VisitFriendDecl(FriendDecl *D) {
866 if (TypeSourceInfo *TSI = D->getFriendType()) {
867 unsigned NumTPLists = D->getFriendTypeNumTemplateParameterLists();
868 for (unsigned i = 0; i < NumTPLists; ++i)
869 printTemplateParameters(D->getFriendTypeTemplateParameterList(i));
870 Out << "friend ";
871 Out << TSI->getType().getAsString(Policy);
872 }
873 else if (FunctionDecl *FD =
874 dyn_cast<FunctionDecl>(D->getFriendDecl())) {
875 Out << "friend ";
876 VisitFunctionDecl(FD);
877 }
878 else if (FunctionTemplateDecl *FTD =
879 dyn_cast<FunctionTemplateDecl>(D->getFriendDecl())) {
880 Out << "friend ";
881 VisitFunctionTemplateDecl(FTD);
882 }
883 else if (ClassTemplateDecl *CTD =
884 dyn_cast<ClassTemplateDecl>(D->getFriendDecl())) {
885 Out << "friend ";
886 VisitRedeclarableTemplateDecl(CTD);
887 }
888
889 if (D->isPackExpansion())
890 Out << "...";
891}
892
893void DeclPrinter::VisitFieldDecl(FieldDecl *D) {
894 // FIXME: add printing of pragma attributes if required.
895 if (!Policy.SuppressSpecifiers && D->isMutable())
896 Out << "mutable ";
897 if (!Policy.SuppressSpecifiers && D->isModulePrivate())
898 Out << "__module_private__ ";
899
900 Out << D->getASTContext().getUnqualifiedObjCPointerType(D->getType()).
901 stream(Policy, D->getName(), Indentation);
902
903 if (D->isBitField()) {
904 Out << " : ";
905 D->getBitWidth()->printPretty(Out, nullptr, Policy, Indentation, "\n",
906 &Context);
907 }
908
909 Expr *Init = D->getInClassInitializer();
910 if (!Policy.SuppressInitializers && Init) {
911 if (D->getInClassInitStyle() == ICIS_ListInit)
912 Out << " ";
913 else
914 Out << " = ";
915 Init->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
916 }
917 prettyPrintAttributes(D);
918}
919
920void DeclPrinter::VisitLabelDecl(LabelDecl *D) {
921 Out << *D << ":";
922}
923
924void DeclPrinter::VisitVarDecl(VarDecl *D) {
925 prettyPrintPragmas(D);
926
927 prettyPrintAttributes(D, AttrPosAsWritten::Left);
928
929 if (const auto *Param = dyn_cast<ParmVarDecl>(D);
930 Param && Param->isExplicitObjectParameter())
931 Out << "this ";
932
933 QualType T = D->getTypeSourceInfo()
934 ? D->getTypeSourceInfo()->getType()
936
937 if (!Policy.SuppressSpecifiers) {
938 StorageClass SC = D->getStorageClass();
939 if (SC != SC_None)
941
942 switch (D->getTSCSpec()) {
943 case TSCS_unspecified:
944 break;
945 case TSCS___thread:
946 Out << "__thread ";
947 break;
949 Out << "_Thread_local ";
950 break;
952 Out << "thread_local ";
953 break;
954 }
955
956 if (D->isModulePrivate())
957 Out << "__module_private__ ";
958
959 if (D->isConstexpr()) {
960 Out << "constexpr ";
961 T.removeLocalConst();
962 }
963 }
964
965 if (!Policy.SuppressTagKeyword && Policy.SuppressScope &&
968
969 printDeclType(T, (isa<ParmVarDecl>(D) && Policy.CleanUglifiedParameters &&
970 D->getIdentifier())
971 ? D->getIdentifier()->deuglifiedName()
972 : D->getName());
973
974 prettyPrintAttributes(D, AttrPosAsWritten::Right);
975
976 Expr *Init = D->getInit();
977 if (!Policy.SuppressInitializers && Init) {
978 bool ImplicitInit = false;
979 if (D->isCXXForRangeDecl()) {
980 // FIXME: We should print the range expression instead.
981 ImplicitInit = true;
982 } else if (CXXConstructExpr *Construct =
983 dyn_cast<CXXConstructExpr>(Init->IgnoreImplicit())) {
984 if (D->getInitStyle() == VarDecl::CallInit &&
985 !Construct->isListInitialization()) {
986 ImplicitInit = Construct->getNumArgs() == 0 ||
987 Construct->getArg(0)->isDefaultArgument();
988 }
989 }
990 if (!ImplicitInit) {
991 if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init))
992 Out << "(";
993 else if (D->getInitStyle() == VarDecl::CInit) {
994 Out << " = ";
995 }
996 PrintingPolicy SubPolicy(Policy);
997 SubPolicy.SuppressSpecifiers = false;
998 SubPolicy.IncludeTagDefinition = false;
999 Init->printPretty(Out, nullptr, SubPolicy, Indentation, "\n", &Context);
1000 if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init))
1001 Out << ")";
1002 }
1003 }
1004}
1005
1006void DeclPrinter::VisitParmVarDecl(ParmVarDecl *D) {
1007 VisitVarDecl(D);
1008}
1009
1010void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
1011 Out << "__asm (";
1012 D->getAsmString()->printPretty(Out, nullptr, Policy, Indentation, "\n",
1013 &Context);
1014 Out << ")";
1015}
1016
1017void DeclPrinter::VisitTopLevelStmtDecl(TopLevelStmtDecl *D) {
1018 assert(D->getStmt());
1019 D->getStmt()->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
1020}
1021
1022void DeclPrinter::VisitImportDecl(ImportDecl *D) {
1023 Out << "@import " << D->getImportedModule()->getFullModuleName()
1024 << ";\n";
1025}
1026
1027void DeclPrinter::VisitStaticAssertDecl(StaticAssertDecl *D) {
1028 Out << "static_assert(";
1029 D->getAssertExpr()->printPretty(Out, nullptr, Policy, Indentation, "\n",
1030 &Context);
1031 if (Expr *E = D->getMessage()) {
1032 Out << ", ";
1033 E->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
1034 }
1035 Out << ")";
1036}
1037
1038//----------------------------------------------------------------------------
1039// C++ declarations
1040//----------------------------------------------------------------------------
1041void DeclPrinter::VisitNamespaceDecl(NamespaceDecl *D) {
1042 if (D->isInline())
1043 Out << "inline ";
1044
1045 Out << "namespace ";
1046 if (D->getDeclName())
1047 Out << D->getDeclName() << ' ';
1048 Out << "{\n";
1049
1050 VisitDeclContext(D);
1051 Indent() << "}";
1052}
1053
1054void DeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1055 Out << "using namespace ";
1056 if (D->getQualifier())
1057 D->getQualifier()->print(Out, Policy);
1058 Out << *D->getNominatedNamespaceAsWritten();
1059}
1060
1061void DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1062 Out << "namespace " << *D << " = ";
1063 if (D->getQualifier())
1064 D->getQualifier()->print(Out, Policy);
1065 Out << *D->getAliasedNamespace();
1066}
1067
1068void DeclPrinter::VisitEmptyDecl(EmptyDecl *D) {
1069 prettyPrintAttributes(D);
1070}
1071
1072void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
1073 // FIXME: add printing of pragma attributes if required.
1074 if (!Policy.SuppressSpecifiers && D->isModulePrivate())
1075 Out << "__module_private__ ";
1076
1077 Out << D->getKindName() << ' ';
1078
1079 // FIXME: Move before printing the decl kind to match the behavior of the
1080 // attribute printing for variables and function where they are printed first.
1081 if (prettyPrintAttributes(D, AttrPosAsWritten::Left))
1082 Out << ' ';
1083
1084 if (D->getIdentifier()) {
1085 if (auto *NNS = D->getQualifier())
1086 NNS->print(Out, Policy);
1087 Out << *D;
1088
1089 if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1090 const TemplateParameterList *TParams =
1091 S->getSpecializedTemplate()->getTemplateParameters();
1092 const ASTTemplateArgumentListInfo *TArgAsWritten =
1093 S->getTemplateArgsAsWritten();
1094 if (TArgAsWritten && !Policy.PrintCanonicalTypes)
1095 printTemplateArguments(TArgAsWritten->arguments(), TParams);
1096 else
1097 printTemplateArguments(S->getTemplateArgs().asArray(), TParams);
1098 }
1099 }
1100
1101 prettyPrintAttributes(D, AttrPosAsWritten::Right);
1102
1103 if (D->isCompleteDefinition()) {
1104 Out << ' ';
1105 // Print the base classes
1106 if (D->getNumBases()) {
1107 Out << ": ";
1108 for (CXXRecordDecl::base_class_iterator Base = D->bases_begin(),
1109 BaseEnd = D->bases_end(); Base != BaseEnd; ++Base) {
1110 if (Base != D->bases_begin())
1111 Out << ", ";
1112
1113 if (Base->isVirtual())
1114 Out << "virtual ";
1115
1116 AccessSpecifier AS = Base->getAccessSpecifierAsWritten();
1117 if (AS != AS_none) {
1118 Print(AS);
1119 Out << " ";
1120 }
1121 Out << Base->getType().getAsString(Policy);
1122
1123 if (Base->isPackExpansion())
1124 Out << "...";
1125 }
1126 Out << ' ';
1127 }
1128
1129 // Print the class definition
1130 // FIXME: Doesn't print access specifiers, e.g., "public:"
1131 if (Policy.TerseOutput) {
1132 Out << "{}";
1133 } else {
1134 Out << "{\n";
1135 VisitDeclContext(D);
1136 Indent() << "}";
1137 }
1138 }
1139}
1140
1141void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1142 const char *l;
1143 if (D->getLanguage() == LinkageSpecLanguageIDs::C)
1144 l = "C";
1145 else {
1146 assert(D->getLanguage() == LinkageSpecLanguageIDs::CXX &&
1147 "unknown language in linkage specification");
1148 l = "C++";
1149 }
1150
1151 Out << "extern \"" << l << "\" ";
1152 if (D->hasBraces()) {
1153 Out << "{\n";
1154 VisitDeclContext(D);
1155 Indent() << "}";
1156 } else
1157 Visit(*D->decls_begin());
1158}
1159
1160void DeclPrinter::printTemplateParameters(const TemplateParameterList *Params,
1161 bool OmitTemplateKW) {
1162 assert(Params);
1163
1164 // Don't print invented template parameter lists.
1165 if (!Params->empty() && Params->getParam(0)->isImplicit())
1166 return;
1167
1168 if (!OmitTemplateKW)
1169 Out << "template ";
1170 Out << '<';
1171
1172 bool NeedComma = false;
1173 for (const Decl *Param : *Params) {
1174 if (Param->isImplicit())
1175 continue;
1176
1177 if (NeedComma)
1178 Out << ", ";
1179 else
1180 NeedComma = true;
1181
1182 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
1183 VisitTemplateTypeParmDecl(TTP);
1184 } else if (auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
1185 VisitNonTypeTemplateParmDecl(NTTP);
1186 } else if (auto TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
1187 VisitTemplateDecl(TTPD);
1188 // FIXME: print the default argument, if present.
1189 }
1190 }
1191
1192 Out << '>';
1193
1194 if (const Expr *RequiresClause = Params->getRequiresClause()) {
1195 Out << " requires ";
1196 RequiresClause->printPretty(Out, nullptr, Policy, Indentation, "\n",
1197 &Context);
1198 }
1199
1200 if (!OmitTemplateKW)
1201 Out << ' ';
1202}
1203
1204void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgument> Args,
1205 const TemplateParameterList *Params) {
1206 Out << "<";
1207 for (size_t I = 0, E = Args.size(); I < E; ++I) {
1208 if (I)
1209 Out << ", ";
1210 if (!Params)
1211 Args[I].print(Policy, Out, /*IncludeType*/ true);
1212 else
1213 Args[I].print(Policy, Out,
1215 Policy, Params, I));
1216 }
1217 Out << ">";
1218}
1219
1220void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
1221 const TemplateParameterList *Params) {
1222 Out << "<";
1223 for (size_t I = 0, E = Args.size(); I < E; ++I) {
1224 if (I)
1225 Out << ", ";
1226 if (!Params)
1227 Args[I].getArgument().print(Policy, Out, /*IncludeType*/ true);
1228 else
1229 Args[I].getArgument().print(
1230 Policy, Out,
1232 I));
1233 }
1234 Out << ">";
1235}
1236
1237void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
1238 printTemplateParameters(D->getTemplateParameters());
1239
1240 if (const TemplateTemplateParmDecl *TTP =
1241 dyn_cast<TemplateTemplateParmDecl>(D)) {
1242 if (TTP->wasDeclaredWithTypename())
1243 Out << "typename";
1244 else
1245 Out << "class";
1246
1247 if (TTP->isParameterPack())
1248 Out << " ...";
1249 else if (TTP->getDeclName())
1250 Out << ' ';
1251
1252 if (TTP->getDeclName()) {
1253 if (Policy.CleanUglifiedParameters && TTP->getIdentifier())
1254 Out << TTP->getIdentifier()->deuglifiedName();
1255 else
1256 Out << TTP->getDeclName();
1257 }
1258 } else if (auto *TD = D->getTemplatedDecl())
1259 Visit(TD);
1260 else if (const auto *Concept = dyn_cast<ConceptDecl>(D)) {
1261 Out << "concept " << Concept->getName() << " = " ;
1262 Concept->getConstraintExpr()->printPretty(Out, nullptr, Policy, Indentation,
1263 "\n", &Context);
1264 }
1265}
1266
1267void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
1268 prettyPrintPragmas(D->getTemplatedDecl());
1269 // Print any leading template parameter lists.
1270 if (const FunctionDecl *FD = D->getTemplatedDecl()) {
1271 for (unsigned I = 0, NumTemplateParams = FD->getNumTemplateParameterLists();
1272 I < NumTemplateParams; ++I)
1273 printTemplateParameters(FD->getTemplateParameterList(I));
1274 }
1275 VisitRedeclarableTemplateDecl(D);
1276 // Declare target attribute is special one, natural spelling for the pragma
1277 // assumes "ending" construct so print it here.
1278 if (D->getTemplatedDecl()->hasAttr<OMPDeclareTargetDeclAttr>())
1279 Out << "#pragma omp end declare target\n";
1280
1281 // Never print "instantiations" for deduction guides (they don't really
1282 // have them).
1283 if (PrintInstantiation &&
1284 !isa<CXXDeductionGuideDecl>(D->getTemplatedDecl())) {
1285 FunctionDecl *PrevDecl = D->getTemplatedDecl();
1286 const FunctionDecl *Def;
1287 if (PrevDecl->isDefined(Def) && Def != PrevDecl)
1288 return;
1289 for (auto *I : D->specializations())
1290 if (I->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) {
1291 if (!PrevDecl->isThisDeclarationADefinition())
1292 Out << ";\n";
1293 Indent();
1294 prettyPrintPragmas(I);
1295 Visit(I);
1296 }
1297 }
1298}
1299
1300void DeclPrinter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
1301 VisitRedeclarableTemplateDecl(D);
1302
1303 if (PrintInstantiation) {
1304 for (auto *I : D->specializations())
1305 if (I->getSpecializationKind() == TSK_ImplicitInstantiation) {
1306 if (D->isThisDeclarationADefinition())
1307 Out << ";";
1308 Out << "\n";
1309 Indent();
1310 Visit(I);
1311 }
1312 }
1313}
1314
1315void DeclPrinter::VisitClassTemplateSpecializationDecl(
1317 Out << "template<> ";
1318 VisitCXXRecordDecl(D);
1319}
1320
1321void DeclPrinter::VisitClassTemplatePartialSpecializationDecl(
1323 printTemplateParameters(D->getTemplateParameters());
1324 VisitCXXRecordDecl(D);
1325}
1326
1327//----------------------------------------------------------------------------
1328// Objective-C declarations
1329//----------------------------------------------------------------------------
1330
1331void DeclPrinter::PrintObjCMethodType(ASTContext &Ctx,
1333 QualType T) {
1334 Out << '(';
1336 Out << "in ";
1338 Out << "inout ";
1340 Out << "out ";
1342 Out << "bycopy ";
1344 Out << "byref ";
1346 Out << "oneway ";
1348 if (auto nullability = AttributedType::stripOuterNullability(T))
1349 Out << getNullabilitySpelling(*nullability, true) << ' ';
1350 }
1351
1352 Out << Ctx.getUnqualifiedObjCPointerType(T).getAsString(Policy);
1353 Out << ')';
1354}
1355
1356void DeclPrinter::PrintObjCTypeParams(ObjCTypeParamList *Params) {
1357 Out << "<";
1358 unsigned First = true;
1359 for (auto *Param : *Params) {
1360 if (First) {
1361 First = false;
1362 } else {
1363 Out << ", ";
1364 }
1365
1366 switch (Param->getVariance()) {
1368 break;
1369
1371 Out << "__covariant ";
1372 break;
1373
1375 Out << "__contravariant ";
1376 break;
1377 }
1378
1379 Out << Param->getDeclName();
1380
1381 if (Param->hasExplicitBound()) {
1382 Out << " : " << Param->getUnderlyingType().getAsString(Policy);
1383 }
1384 }
1385 Out << ">";
1386}
1387
1388void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) {
1389 if (OMD->isInstanceMethod())
1390 Out << "- ";
1391 else
1392 Out << "+ ";
1393 if (!OMD->getReturnType().isNull()) {
1394 PrintObjCMethodType(OMD->getASTContext(), OMD->getObjCDeclQualifier(),
1395 OMD->getReturnType());
1396 }
1397
1398 std::string name = OMD->getSelector().getAsString();
1399 std::string::size_type pos, lastPos = 0;
1400 for (const auto *PI : OMD->parameters()) {
1401 // FIXME: selector is missing here!
1402 pos = name.find_first_of(':', lastPos);
1403 if (lastPos != 0)
1404 Out << " ";
1405 Out << name.substr(lastPos, pos - lastPos) << ':';
1406 PrintObjCMethodType(OMD->getASTContext(),
1407 PI->getObjCDeclQualifier(),
1408 PI->getType());
1409 Out << *PI;
1410 lastPos = pos + 1;
1411 }
1412
1413 if (OMD->param_begin() == OMD->param_end())
1414 Out << name;
1415
1416 if (OMD->isVariadic())
1417 Out << ", ...";
1418
1419 prettyPrintAttributes(OMD);
1420
1421 if (OMD->getBody() && !Policy.TerseOutput) {
1422 Out << ' ';
1423 OMD->getBody()->printPretty(Out, nullptr, Policy, Indentation, "\n",
1424 &Context);
1425 }
1426 else if (Policy.PolishForDeclaration)
1427 Out << ';';
1428}
1429
1430void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) {
1431 std::string I = OID->getNameAsString();
1432 ObjCInterfaceDecl *SID = OID->getSuperClass();
1433
1434 bool eolnOut = false;
1435 if (SID)
1436 Out << "@implementation " << I << " : " << *SID;
1437 else
1438 Out << "@implementation " << I;
1439
1440 if (OID->ivar_size() > 0) {
1441 Out << "{\n";
1442 eolnOut = true;
1443 Indentation += Policy.Indentation;
1444 for (const auto *I : OID->ivars()) {
1445 Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
1446 getAsString(Policy) << ' ' << *I << ";\n";
1447 }
1448 Indentation -= Policy.Indentation;
1449 Out << "}\n";
1450 }
1451 else if (SID || (OID->decls_begin() != OID->decls_end())) {
1452 Out << "\n";
1453 eolnOut = true;
1454 }
1455 VisitDeclContext(OID, false);
1456 if (!eolnOut)
1457 Out << "\n";
1458 Out << "@end";
1459}
1460
1461void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
1462 std::string I = OID->getNameAsString();
1463 ObjCInterfaceDecl *SID = OID->getSuperClass();
1464
1465 if (!OID->isThisDeclarationADefinition()) {
1466 Out << "@class " << I;
1467
1468 if (auto TypeParams = OID->getTypeParamListAsWritten()) {
1469 PrintObjCTypeParams(TypeParams);
1470 }
1471
1472 Out << ";";
1473 return;
1474 }
1475 bool eolnOut = false;
1476 if (OID->hasAttrs()) {
1477 prettyPrintAttributes(OID);
1478 Out << "\n";
1479 }
1480
1481 Out << "@interface " << I;
1482
1483 if (auto TypeParams = OID->getTypeParamListAsWritten()) {
1484 PrintObjCTypeParams(TypeParams);
1485 }
1486
1487 if (SID)
1488 Out << " : " << QualType(OID->getSuperClassType(), 0).getAsString(Policy);
1489
1490 // Protocols?
1491 const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();
1492 if (!Protocols.empty()) {
1493 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
1494 E = Protocols.end(); I != E; ++I)
1495 Out << (I == Protocols.begin() ? '<' : ',') << **I;
1496 Out << "> ";
1497 }
1498
1499 if (OID->ivar_size() > 0) {
1500 Out << "{\n";
1501 eolnOut = true;
1502 Indentation += Policy.Indentation;
1503 for (const auto *I : OID->ivars()) {
1504 Indent() << I->getASTContext()
1505 .getUnqualifiedObjCPointerType(I->getType())
1506 .getAsString(Policy) << ' ' << *I << ";\n";
1507 }
1508 Indentation -= Policy.Indentation;
1509 Out << "}\n";
1510 }
1511 else if (SID || (OID->decls_begin() != OID->decls_end())) {
1512 Out << "\n";
1513 eolnOut = true;
1514 }
1515
1516 VisitDeclContext(OID, false);
1517 if (!eolnOut)
1518 Out << "\n";
1519 Out << "@end";
1520 // FIXME: implement the rest...
1521}
1522
1523void DeclPrinter::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1524 if (!PID->isThisDeclarationADefinition()) {
1525 Out << "@protocol " << *PID << ";\n";
1526 return;
1527 }
1528 // Protocols?
1529 const ObjCList<ObjCProtocolDecl> &Protocols = PID->getReferencedProtocols();
1530 if (!Protocols.empty()) {
1531 Out << "@protocol " << *PID;
1532 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
1533 E = Protocols.end(); I != E; ++I)
1534 Out << (I == Protocols.begin() ? '<' : ',') << **I;
1535 Out << ">\n";
1536 } else
1537 Out << "@protocol " << *PID << '\n';
1538 VisitDeclContext(PID, false);
1539 Out << "@end";
1540}
1541
1542void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) {
1543 Out << "@implementation ";
1544 if (const auto *CID = PID->getClassInterface())
1545 Out << *CID;
1546 else
1547 Out << "<<error-type>>";
1548 Out << '(' << *PID << ")\n";
1549
1550 VisitDeclContext(PID, false);
1551 Out << "@end";
1552 // FIXME: implement the rest...
1553}
1554
1555void DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) {
1556 Out << "@interface ";
1557 if (const auto *CID = PID->getClassInterface())
1558 Out << *CID;
1559 else
1560 Out << "<<error-type>>";
1561 if (auto TypeParams = PID->getTypeParamList()) {
1562 PrintObjCTypeParams(TypeParams);
1563 }
1564 Out << "(" << *PID << ")\n";
1565 if (PID->ivar_size() > 0) {
1566 Out << "{\n";
1567 Indentation += Policy.Indentation;
1568 for (const auto *I : PID->ivars())
1569 Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
1570 getAsString(Policy) << ' ' << *I << ";\n";
1571 Indentation -= Policy.Indentation;
1572 Out << "}\n";
1573 }
1574
1575 VisitDeclContext(PID, false);
1576 Out << "@end";
1577
1578 // FIXME: implement the rest...
1579}
1580
1581void DeclPrinter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID) {
1582 Out << "@compatibility_alias " << *AID
1583 << ' ' << *AID->getClassInterface() << ";\n";
1584}
1585
1586/// PrintObjCPropertyDecl - print a property declaration.
1587///
1588/// Print attributes in the following order:
1589/// - class
1590/// - nonatomic | atomic
1591/// - assign | retain | strong | copy | weak | unsafe_unretained
1592/// - readwrite | readonly
1593/// - getter & setter
1594/// - nullability
1595void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
1597 Out << "@required\n";
1599 Out << "@optional\n";
1600
1601 QualType T = PDecl->getType();
1602
1603 Out << "@property";
1605 bool first = true;
1606 Out << "(";
1608 Out << (first ? "" : ", ") << "class";
1609 first = false;
1610 }
1611
1613 Out << (first ? "" : ", ") << "direct";
1614 first = false;
1615 }
1616
1617 if (PDecl->getPropertyAttributes() &
1619 Out << (first ? "" : ", ") << "nonatomic";
1620 first = false;
1621 }
1623 Out << (first ? "" : ", ") << "atomic";
1624 first = false;
1625 }
1626
1628 Out << (first ? "" : ", ") << "assign";
1629 first = false;
1630 }
1632 Out << (first ? "" : ", ") << "retain";
1633 first = false;
1634 }
1635
1637 Out << (first ? "" : ", ") << "strong";
1638 first = false;
1639 }
1641 Out << (first ? "" : ", ") << "copy";
1642 first = false;
1643 }
1645 Out << (first ? "" : ", ") << "weak";
1646 first = false;
1647 }
1648 if (PDecl->getPropertyAttributes() &
1650 Out << (first ? "" : ", ") << "unsafe_unretained";
1651 first = false;
1652 }
1653
1654 if (PDecl->getPropertyAttributes() &
1656 Out << (first ? "" : ", ") << "readwrite";
1657 first = false;
1658 }
1660 Out << (first ? "" : ", ") << "readonly";
1661 first = false;
1662 }
1663
1665 Out << (first ? "" : ", ") << "getter = ";
1666 PDecl->getGetterName().print(Out);
1667 first = false;
1668 }
1670 Out << (first ? "" : ", ") << "setter = ";
1671 PDecl->getSetterName().print(Out);
1672 first = false;
1673 }
1674
1675 if (PDecl->getPropertyAttributes() &
1677 if (auto nullability = AttributedType::stripOuterNullability(T)) {
1678 if (*nullability == NullabilityKind::Unspecified &&
1679 (PDecl->getPropertyAttributes() &
1681 Out << (first ? "" : ", ") << "null_resettable";
1682 } else {
1683 Out << (first ? "" : ", ")
1684 << getNullabilitySpelling(*nullability, true);
1685 }
1686 first = false;
1687 }
1688 }
1689
1690 (void) first; // Silence dead store warning due to idiomatic code.
1691 Out << ")";
1692 }
1693 std::string TypeStr = PDecl->getASTContext().getUnqualifiedObjCPointerType(T).
1694 getAsString(Policy);
1695 Out << ' ' << TypeStr;
1696 if (!StringRef(TypeStr).ends_with("*"))
1697 Out << ' ';
1698 Out << *PDecl;
1699 if (Policy.PolishForDeclaration)
1700 Out << ';';
1701}
1702
1703void DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) {
1705 Out << "@synthesize ";
1706 else
1707 Out << "@dynamic ";
1708 Out << *PID->getPropertyDecl();
1709 if (PID->getPropertyIvarDecl())
1710 Out << '=' << *PID->getPropertyIvarDecl();
1711}
1712
1713void DeclPrinter::VisitUsingDecl(UsingDecl *D) {
1714 if (!D->isAccessDeclaration())
1715 Out << "using ";
1716 if (D->hasTypename())
1717 Out << "typename ";
1718 D->getQualifier()->print(Out, Policy);
1719
1720 // Use the correct record name when the using declaration is used for
1721 // inheriting constructors.
1722 for (const auto *Shadow : D->shadows()) {
1723 if (const auto *ConstructorShadow =
1724 dyn_cast<ConstructorUsingShadowDecl>(Shadow)) {
1725 assert(Shadow->getDeclContext() == ConstructorShadow->getDeclContext());
1726 Out << *ConstructorShadow->getNominatedBaseClass();
1727 return;
1728 }
1729 }
1730 Out << *D;
1731}
1732
1733void DeclPrinter::VisitUsingEnumDecl(UsingEnumDecl *D) {
1734 Out << "using enum " << D->getEnumDecl();
1735}
1736
1737void
1738DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
1739 Out << "using typename ";
1740 D->getQualifier()->print(Out, Policy);
1741 Out << D->getDeclName();
1742}
1743
1744void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1745 if (!D->isAccessDeclaration())
1746 Out << "using ";
1747 D->getQualifier()->print(Out, Policy);
1748 Out << D->getDeclName();
1749}
1750
1751void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) {
1752 // ignore
1753}
1754
1755void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
1756 Out << "#pragma omp threadprivate";
1757 if (!D->varlist_empty()) {
1758 for (OMPThreadPrivateDecl::varlist_iterator I = D->varlist_begin(),
1759 E = D->varlist_end();
1760 I != E; ++I) {
1761 Out << (I == D->varlist_begin() ? '(' : ',');
1762 NamedDecl *ND = cast<DeclRefExpr>(*I)->getDecl();
1763 ND->printQualifiedName(Out);
1764 }
1765 Out << ")";
1766 }
1767}
1768
1769void DeclPrinter::VisitHLSLBufferDecl(HLSLBufferDecl *D) {
1770 if (D->isCBuffer())
1771 Out << "cbuffer ";
1772 else
1773 Out << "tbuffer ";
1774
1775 Out << *D;
1776
1777 prettyPrintAttributes(D);
1778
1779 Out << " {\n";
1780 VisitDeclContext(D);
1781 Indent() << "}";
1782}
1783
1784void DeclPrinter::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
1785 Out << "#pragma omp allocate";
1786 if (!D->varlist_empty()) {
1787 for (OMPAllocateDecl::varlist_iterator I = D->varlist_begin(),
1788 E = D->varlist_end();
1789 I != E; ++I) {
1790 Out << (I == D->varlist_begin() ? '(' : ',');
1791 NamedDecl *ND = cast<DeclRefExpr>(*I)->getDecl();
1792 ND->printQualifiedName(Out);
1793 }
1794 Out << ")";
1795 }
1796 if (!D->clauselist_empty()) {
1797 OMPClausePrinter Printer(Out, Policy);
1798 for (OMPClause *C : D->clauselists()) {
1799 Out << " ";
1800 Printer.Visit(C);
1801 }
1802 }
1803}
1804
1805void DeclPrinter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
1806 Out << "#pragma omp requires ";
1807 if (!D->clauselist_empty()) {
1808 OMPClausePrinter Printer(Out, Policy);
1809 for (auto I = D->clauselist_begin(), E = D->clauselist_end(); I != E; ++I)
1810 Printer.Visit(*I);
1811 }
1812}
1813
1814void DeclPrinter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
1815 if (!D->isInvalidDecl()) {
1816 Out << "#pragma omp declare reduction (";
1817 if (D->getDeclName().getNameKind() == DeclarationName::CXXOperatorName) {
1818 const char *OpName =
1819 getOperatorSpelling(D->getDeclName().getCXXOverloadedOperator());
1820 assert(OpName && "not an overloaded operator");
1821 Out << OpName;
1822 } else {
1823 assert(D->getDeclName().isIdentifier());
1824 D->printName(Out, Policy);
1825 }
1826 Out << " : ";
1827 D->getType().print(Out, Policy);
1828 Out << " : ";
1829 D->getCombiner()->printPretty(Out, nullptr, Policy, 0, "\n", &Context);
1830 Out << ")";
1831 if (auto *Init = D->getInitializer()) {
1832 Out << " initializer(";
1833 switch (D->getInitializerKind()) {
1835 Out << "omp_priv(";
1836 break;
1838 Out << "omp_priv = ";
1839 break;
1841 break;
1842 }
1843 Init->printPretty(Out, nullptr, Policy, 0, "\n", &Context);
1844 if (D->getInitializerKind() == OMPDeclareReductionInitKind::Direct)
1845 Out << ")";
1846 Out << ")";
1847 }
1848 }
1849}
1850
1851void DeclPrinter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
1852 if (!D->isInvalidDecl()) {
1853 Out << "#pragma omp declare mapper (";
1854 D->printName(Out, Policy);
1855 Out << " : ";
1856 D->getType().print(Out, Policy);
1857 Out << " ";
1858 Out << D->getVarName();
1859 Out << ")";
1860 if (!D->clauselist_empty()) {
1861 OMPClausePrinter Printer(Out, Policy);
1862 for (auto *C : D->clauselists()) {
1863 Out << " ";
1864 Printer.Visit(C);
1865 }
1866 }
1867 }
1868}
1869
1870void DeclPrinter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
1871 D->getInit()->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
1872}
1873
1874void DeclPrinter::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *TTP) {
1875 if (const TypeConstraint *TC = TTP->getTypeConstraint())
1876 TC->print(Out, Policy);
1877 else if (TTP->wasDeclaredWithTypename())
1878 Out << "typename";
1879 else
1880 Out << "class";
1881
1882 if (TTP->isParameterPack())
1883 Out << " ...";
1884 else if (TTP->getDeclName())
1885 Out << ' ';
1886
1887 if (TTP->getDeclName()) {
1888 if (Policy.CleanUglifiedParameters && TTP->getIdentifier())
1889 Out << TTP->getIdentifier()->deuglifiedName();
1890 else
1891 Out << TTP->getDeclName();
1892 }
1893
1894 if (TTP->hasDefaultArgument()) {
1895 Out << " = ";
1896 TTP->getDefaultArgument().getArgument().print(Policy, Out,
1897 /*IncludeType=*/false);
1898 }
1899}
1900
1901void DeclPrinter::VisitNonTypeTemplateParmDecl(
1902 const NonTypeTemplateParmDecl *NTTP) {
1903 StringRef Name;
1904 if (IdentifierInfo *II = NTTP->getIdentifier())
1905 Name =
1906 Policy.CleanUglifiedParameters ? II->deuglifiedName() : II->getName();
1907 printDeclType(NTTP->getType(), Name, NTTP->isParameterPack());
1908
1909 if (NTTP->hasDefaultArgument()) {
1910 Out << " = ";
1911 NTTP->getDefaultArgument().getArgument().print(Policy, Out,
1912 /*IncludeType=*/false);
1913 }
1914}
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:187
const LangOptions & getLangOpts() const
Definition: ASTContext.h:797
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:713
QualType getUnqualifiedObjCPointerType(QualType type) const
getUnqualifiedObjCPointerType - Returns version of Objective-C pointer type with lifetime qualifier r...
Definition: ASTContext.h:2245
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:3566
Attr - This represents one attribute.
Definition: Attr.h:42
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:4865
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: Type.h:6375
Pointer to a block type.
Definition: Type.h:3397
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:2539
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2866
Represents a C++ deduction guide declaration.
Definition: DeclCXX.h:1956
TemplateDecl * getDeducedTemplate() const
Get the template for which this guide performs deduction.
Definition: DeclCXX.h:1998
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:2307
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
Definition: DeclBase.h:1436
DeclContext * getParent()
getParent - Returns the containing DeclContext.
Definition: DeclBase.h:2090
bool isTranslationUnit() const
Definition: DeclBase.h:2166
void dumpDeclContext() const
decl_iterator decls_end() const
Definition: DeclBase.h:2352
decl_iterator decls_begin() const
Definition: DeclBase.cpp:1622
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:649
bool hasAttrs() const
Definition: DeclBase.h:525
ASTContext & getASTContext() const LLVM_READONLY
Definition: DeclBase.cpp:523
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
Definition: DeclBase.h:600
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:1077
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:595
SourceLocation getLocation() const
Definition: DeclBase.h:446
static void printGroup(Decl **Begin, unsigned NumDecls, raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation=0)
AccessSpecifier getAccess() const
Definition: DeclBase.h:514
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
AttrVec & getAttrs()
Definition: DeclBase.h:531
bool hasAttr() const
Definition: DeclBase.h:584
std::string getAsString() const
Retrieve the human-readable string for this name.
TemplateParameterList * getTemplateParameterList(unsigned index) const
Definition: Decl.h:823
unsigned getNumTemplateParameterLists() const
Definition: Decl.h:819
Represents an empty-declaration.
Definition: Decl.h:4909
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:3274
Represents an enum.
Definition: Decl.h:3844
Store information needed for an explicit specifier.
Definition: DeclCXX.h:1901
const Expr * getExpr() const
Definition: DeclCXX.h:1910
static ExplicitSpecifier getFromDecl(FunctionDecl *Function)
Definition: DeclCXX.cpp:2182
bool isSpecified() const
Determine if the declaration had an explicit specifier of any kind.
Definition: DeclCXX.h:1914
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:3030
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:1932
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition: Decl.h:2246
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:3191
Represents a prototype with parameter type info, e.g.
Definition: Type.h:5002
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition: Type.h:5282
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition: Type.h:5395
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition: Type.h:5333
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition: Type.h:5325
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
Definition: Type.h:5291
bool isVariadic() const
Whether this function prototype is variadic.
Definition: Type.h:5379
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition: Type.h:5340
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition: Type.h:5405
Declaration of a template function.
Definition: DeclTemplate.h:957
FunctionType - C99 6.7.5.3 - Function Declarators.
Definition: Type.h:4308
bool isConst() const
Definition: Type.h:4648
bool isRestrict() const
Definition: Type.h:4650
bool isVolatile() const
Definition: Type.h:4649
HLSLBufferDecl - Represent a cbuffer or tbuffer declaration.
Definition: Decl.h:4924
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:4783
Represents the declaration of a label.
Definition: Decl.h:499
Represents a linkage specification.
Definition: DeclCXX.h:2938
This represents a decl that may have a name.
Definition: Decl.h:249
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:270
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:315
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:292
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:3124
Represent a C++ namespace.
Definition: Decl.h:547
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:352
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:909
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:7399
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:6960
Sugar for parentheses used when specifying types.
Definition: Type.h:3161
Represents a parameter to a function.
Definition: Decl.h:1722
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3187
A (possibly-)qualified type.
Definition: Type.h:941
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1008
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:1339
Represents a struct/union/class.
Definition: Decl.h:4145
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3428
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:4062
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:3561
A template argument list.
Definition: DeclTemplate.h:244
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:394
Stores a list of template parameters for a TemplateDecl and its derived classes.
Definition: DeclTemplate.h:73
NamedDecl * getParam(unsigned Idx)
Definition: DeclTemplate.h:144
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:4434
The top declaration context.
Definition: Decl.h:84
Represents the declaration of a typedef-name via a C++11 alias-declaration.
Definition: Decl.h:3532
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:7721
bool isStructureType() const
Definition: Type.cpp:629
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:705
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
Definition: Type.cpp:3088
bool isClassType() const
Definition: Type.cpp:623
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8540
bool isUnionType() const
Definition: Type.cpp:671
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition: Decl.h:3511
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3409
Represents a dependent using declaration which was marked with typename.
Definition: DeclCXX.h:3963
Represents a dependent using declaration which was not marked with typename.
Definition: DeclCXX.h:3866
Represents a C++ using-declaration.
Definition: DeclCXX.h:3516
Represents C++ using-directive.
Definition: DeclCXX.h:3019
Represents a C++ using-enum-declaration.
Definition: DeclCXX.h:3717
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition: DeclCXX.h:3324
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:667
QualType getType() const
Definition: Decl.h:678
Represents a variable declaration or definition.
Definition: Decl.h:879
static const char * getStorageClassSpecifierString(StorageClass SC)
Return the string used to specify the storage class SC.
Definition: Decl.cpp:2103
@ CInit
C-style initialization with assignment.
Definition: Decl.h:884
@ CallInit
Call-style initialization (C++98)
Definition: Decl.h:887
Represents a GCC generic vector type.
Definition: Type.h:4021
@ 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:401
@ 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:1778
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition: Type.h:1781
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition: Type.h:1784
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:93
unsigned SuppressInitializers
Suppress printing of variable initializers.
unsigned IncludeTagDefinition
When true, include the body of a tag definition.
unsigned TerseOutput
Provide a 'terse' output.