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