clang 19.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 }
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) {
649 prettyPrintPragmas(D);
650 prettyPrintAttributes(D, AttrPosAsWritten::Left);
651 }
652
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__ ";
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();
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 =
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
890void DeclPrinter::VisitFieldDecl(FieldDecl *D) {
891 // FIXME: add printing of pragma attributes if required.
892 if (!Policy.SuppressSpecifiers && D->isMutable())
893 Out << "mutable ";
894 if (!Policy.SuppressSpecifiers && D->isModulePrivate())
895 Out << "__module_private__ ";
896
898 stream(Policy, D->getName(), Indentation);
899
900 if (D->isBitField()) {
901 Out << " : ";
902 D->getBitWidth()->printPretty(Out, nullptr, Policy, Indentation, "\n",
903 &Context);
904 }
905
907 if (!Policy.SuppressInitializers && Init) {
909 Out << " ";
910 else
911 Out << " = ";
912 Init->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
913 }
914 prettyPrintAttributes(D);
915}
916
917void DeclPrinter::VisitLabelDecl(LabelDecl *D) {
918 Out << *D << ":";
919}
920
921void DeclPrinter::VisitVarDecl(VarDecl *D) {
922 prettyPrintPragmas(D);
923
924 prettyPrintAttributes(D, AttrPosAsWritten::Left);
925
926 if (const auto *Param = dyn_cast<ParmVarDecl>(D);
927 Param && Param->isExplicitObjectParameter())
928 Out << "this ";
929
931 ? D->getTypeSourceInfo()->getType()
933
934 if (!Policy.SuppressSpecifiers) {
936 if (SC != SC_None)
938
939 switch (D->getTSCSpec()) {
940 case TSCS_unspecified:
941 break;
942 case TSCS___thread:
943 Out << "__thread ";
944 break;
946 Out << "_Thread_local ";
947 break;
949 Out << "thread_local ";
950 break;
951 }
952
953 if (D->isModulePrivate())
954 Out << "__module_private__ ";
955
956 if (D->isConstexpr()) {
957 Out << "constexpr ";
958 T.removeLocalConst();
959 }
960 }
961
962 if (!Policy.SuppressTagKeyword && Policy.SuppressScope &&
965
966 printDeclType(T, (isa<ParmVarDecl>(D) && Policy.CleanUglifiedParameters &&
967 D->getIdentifier())
969 : D->getName());
970
971 prettyPrintAttributes(D, AttrPosAsWritten::Right);
972
973 Expr *Init = D->getInit();
974 if (!Policy.SuppressInitializers && Init) {
975 bool ImplicitInit = false;
976 if (D->isCXXForRangeDecl()) {
977 // FIXME: We should print the range expression instead.
978 ImplicitInit = true;
979 } else if (CXXConstructExpr *Construct =
980 dyn_cast<CXXConstructExpr>(Init->IgnoreImplicit())) {
981 if (D->getInitStyle() == VarDecl::CallInit &&
982 !Construct->isListInitialization()) {
983 ImplicitInit = Construct->getNumArgs() == 0 ||
984 Construct->getArg(0)->isDefaultArgument();
985 }
986 }
987 if (!ImplicitInit) {
988 if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init))
989 Out << "(";
990 else if (D->getInitStyle() == VarDecl::CInit) {
991 Out << " = ";
992 }
993 PrintingPolicy SubPolicy(Policy);
994 SubPolicy.SuppressSpecifiers = false;
995 SubPolicy.IncludeTagDefinition = false;
996 Init->printPretty(Out, nullptr, SubPolicy, Indentation, "\n", &Context);
997 if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init))
998 Out << ")";
999 }
1000 }
1001}
1002
1003void DeclPrinter::VisitParmVarDecl(ParmVarDecl *D) {
1004 VisitVarDecl(D);
1005}
1006
1007void DeclPrinter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) {
1008 Out << "__asm (";
1009 D->getAsmString()->printPretty(Out, nullptr, Policy, Indentation, "\n",
1010 &Context);
1011 Out << ")";
1012}
1013
1014void DeclPrinter::VisitTopLevelStmtDecl(TopLevelStmtDecl *D) {
1015 assert(D->getStmt());
1016 D->getStmt()->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
1017}
1018
1019void DeclPrinter::VisitImportDecl(ImportDecl *D) {
1020 Out << "@import " << D->getImportedModule()->getFullModuleName()
1021 << ";\n";
1022}
1023
1024void DeclPrinter::VisitStaticAssertDecl(StaticAssertDecl *D) {
1025 Out << "static_assert(";
1026 D->getAssertExpr()->printPretty(Out, nullptr, Policy, Indentation, "\n",
1027 &Context);
1028 if (Expr *E = D->getMessage()) {
1029 Out << ", ";
1030 E->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
1031 }
1032 Out << ")";
1033}
1034
1035//----------------------------------------------------------------------------
1036// C++ declarations
1037//----------------------------------------------------------------------------
1038void DeclPrinter::VisitNamespaceDecl(NamespaceDecl *D) {
1039 if (D->isInline())
1040 Out << "inline ";
1041
1042 Out << "namespace ";
1043 if (D->getDeclName())
1044 Out << D->getDeclName() << ' ';
1045 Out << "{\n";
1046
1047 VisitDeclContext(D);
1048 Indent() << "}";
1049}
1050
1051void DeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
1052 Out << "using namespace ";
1053 if (D->getQualifier())
1054 D->getQualifier()->print(Out, Policy);
1055 Out << *D->getNominatedNamespaceAsWritten();
1056}
1057
1058void DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
1059 Out << "namespace " << *D << " = ";
1060 if (D->getQualifier())
1061 D->getQualifier()->print(Out, Policy);
1062 Out << *D->getAliasedNamespace();
1063}
1064
1065void DeclPrinter::VisitEmptyDecl(EmptyDecl *D) {
1066 prettyPrintAttributes(D);
1067}
1068
1069void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
1070 // FIXME: add printing of pragma attributes if required.
1071 if (!Policy.SuppressSpecifiers && D->isModulePrivate())
1072 Out << "__module_private__ ";
1073
1074 Out << D->getKindName() << ' ';
1075
1076 // FIXME: Move before printing the decl kind to match the behavior of the
1077 // attribute printing for variables and function where they are printed first.
1078 if (prettyPrintAttributes(D, AttrPosAsWritten::Left))
1079 Out << ' ';
1080
1081 if (D->getIdentifier()) {
1082 if (auto *NNS = D->getQualifier())
1083 NNS->print(Out, Policy);
1084 Out << *D;
1085
1086 if (auto S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
1087 ArrayRef<TemplateArgument> Args = S->getTemplateArgs().asArray();
1088 if (!Policy.PrintCanonicalTypes)
1089 if (const auto* TSI = S->getTypeAsWritten())
1090 if (const auto *TST =
1091 dyn_cast<TemplateSpecializationType>(TSI->getType()))
1092 Args = TST->template_arguments();
1093 printTemplateArguments(
1094 Args, S->getSpecializedTemplate()->getTemplateParameters());
1095 }
1096 }
1097
1098 prettyPrintAttributes(D, AttrPosAsWritten::Right);
1099
1100 if (D->isCompleteDefinition()) {
1101 Out << ' ';
1102 // Print the base classes
1103 if (D->getNumBases()) {
1104 Out << ": ";
1105 for (CXXRecordDecl::base_class_iterator Base = D->bases_begin(),
1106 BaseEnd = D->bases_end(); Base != BaseEnd; ++Base) {
1107 if (Base != D->bases_begin())
1108 Out << ", ";
1109
1110 if (Base->isVirtual())
1111 Out << "virtual ";
1112
1113 AccessSpecifier AS = Base->getAccessSpecifierAsWritten();
1114 if (AS != AS_none) {
1115 Print(AS);
1116 Out << " ";
1117 }
1118 Out << Base->getType().getAsString(Policy);
1119
1120 if (Base->isPackExpansion())
1121 Out << "...";
1122 }
1123 Out << ' ';
1124 }
1125
1126 // Print the class definition
1127 // FIXME: Doesn't print access specifiers, e.g., "public:"
1128 if (Policy.TerseOutput) {
1129 Out << "{}";
1130 } else {
1131 Out << "{\n";
1132 VisitDeclContext(D);
1133 Indent() << "}";
1134 }
1135 }
1136}
1137
1138void DeclPrinter::VisitLinkageSpecDecl(LinkageSpecDecl *D) {
1139 const char *l;
1141 l = "C";
1142 else {
1144 "unknown language in linkage specification");
1145 l = "C++";
1146 }
1147
1148 Out << "extern \"" << l << "\" ";
1149 if (D->hasBraces()) {
1150 Out << "{\n";
1151 VisitDeclContext(D);
1152 Indent() << "}";
1153 } else
1154 Visit(*D->decls_begin());
1155}
1156
1157void DeclPrinter::printTemplateParameters(const TemplateParameterList *Params,
1158 bool OmitTemplateKW) {
1159 assert(Params);
1160
1161 // Don't print invented template parameter lists.
1162 if (!Params->empty() && Params->getParam(0)->isImplicit())
1163 return;
1164
1165 if (!OmitTemplateKW)
1166 Out << "template ";
1167 Out << '<';
1168
1169 bool NeedComma = false;
1170 for (const Decl *Param : *Params) {
1171 if (Param->isImplicit())
1172 continue;
1173
1174 if (NeedComma)
1175 Out << ", ";
1176 else
1177 NeedComma = true;
1178
1179 if (const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
1180 VisitTemplateTypeParmDecl(TTP);
1181 } else if (auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
1182 VisitNonTypeTemplateParmDecl(NTTP);
1183 } else if (auto TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
1184 VisitTemplateDecl(TTPD);
1185 // FIXME: print the default argument, if present.
1186 }
1187 }
1188
1189 Out << '>';
1190 if (!OmitTemplateKW)
1191 Out << ' ';
1192}
1193
1194void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgument> Args,
1195 const TemplateParameterList *Params) {
1196 Out << "<";
1197 for (size_t I = 0, E = Args.size(); I < E; ++I) {
1198 if (I)
1199 Out << ", ";
1200 if (!Params)
1201 Args[I].print(Policy, Out, /*IncludeType*/ true);
1202 else
1203 Args[I].print(Policy, Out,
1205 Policy, Params, I));
1206 }
1207 Out << ">";
1208}
1209
1210void DeclPrinter::printTemplateArguments(ArrayRef<TemplateArgumentLoc> Args,
1211 const TemplateParameterList *Params) {
1212 Out << "<";
1213 for (size_t I = 0, E = Args.size(); I < E; ++I) {
1214 if (I)
1215 Out << ", ";
1216 if (!Params)
1217 Args[I].getArgument().print(Policy, Out, /*IncludeType*/ true);
1218 else
1219 Args[I].getArgument().print(
1220 Policy, Out,
1222 I));
1223 }
1224 Out << ">";
1225}
1226
1227void DeclPrinter::VisitTemplateDecl(const TemplateDecl *D) {
1228 printTemplateParameters(D->getTemplateParameters());
1229
1230 if (const TemplateTemplateParmDecl *TTP =
1231 dyn_cast<TemplateTemplateParmDecl>(D)) {
1232 if (TTP->wasDeclaredWithTypename())
1233 Out << "typename";
1234 else
1235 Out << "class";
1236
1237 if (TTP->isParameterPack())
1238 Out << " ...";
1239 else if (TTP->getDeclName())
1240 Out << ' ';
1241
1242 if (TTP->getDeclName()) {
1243 if (Policy.CleanUglifiedParameters && TTP->getIdentifier())
1244 Out << TTP->getIdentifier()->deuglifiedName();
1245 else
1246 Out << TTP->getDeclName();
1247 }
1248 } else if (auto *TD = D->getTemplatedDecl())
1249 Visit(TD);
1250 else if (const auto *Concept = dyn_cast<ConceptDecl>(D)) {
1251 Out << "concept " << Concept->getName() << " = " ;
1252 Concept->getConstraintExpr()->printPretty(Out, nullptr, Policy, Indentation,
1253 "\n", &Context);
1254 }
1255}
1256
1257void DeclPrinter::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) {
1258 prettyPrintPragmas(D->getTemplatedDecl());
1259 // Print any leading template parameter lists.
1260 if (const FunctionDecl *FD = D->getTemplatedDecl()) {
1261 for (unsigned I = 0, NumTemplateParams = FD->getNumTemplateParameterLists();
1262 I < NumTemplateParams; ++I)
1263 printTemplateParameters(FD->getTemplateParameterList(I));
1264 }
1265 VisitRedeclarableTemplateDecl(D);
1266 // Declare target attribute is special one, natural spelling for the pragma
1267 // assumes "ending" construct so print it here.
1268 if (D->getTemplatedDecl()->hasAttr<OMPDeclareTargetDeclAttr>())
1269 Out << "#pragma omp end declare target\n";
1270
1271 // Never print "instantiations" for deduction guides (they don't really
1272 // have them).
1273 if (PrintInstantiation &&
1274 !isa<CXXDeductionGuideDecl>(D->getTemplatedDecl())) {
1275 FunctionDecl *PrevDecl = D->getTemplatedDecl();
1276 const FunctionDecl *Def;
1277 if (PrevDecl->isDefined(Def) && Def != PrevDecl)
1278 return;
1279 for (auto *I : D->specializations())
1280 if (I->getTemplateSpecializationKind() == TSK_ImplicitInstantiation) {
1281 if (!PrevDecl->isThisDeclarationADefinition())
1282 Out << ";\n";
1283 Indent();
1284 prettyPrintPragmas(I);
1285 Visit(I);
1286 }
1287 }
1288}
1289
1290void DeclPrinter::VisitClassTemplateDecl(ClassTemplateDecl *D) {
1291 VisitRedeclarableTemplateDecl(D);
1292
1293 if (PrintInstantiation) {
1294 for (auto *I : D->specializations())
1295 if (I->getSpecializationKind() == TSK_ImplicitInstantiation) {
1297 Out << ";";
1298 Out << "\n";
1299 Indent();
1300 Visit(I);
1301 }
1302 }
1303}
1304
1305void DeclPrinter::VisitClassTemplateSpecializationDecl(
1307 Out << "template<> ";
1308 VisitCXXRecordDecl(D);
1309}
1310
1311void DeclPrinter::VisitClassTemplatePartialSpecializationDecl(
1313 printTemplateParameters(D->getTemplateParameters());
1314 VisitCXXRecordDecl(D);
1315}
1316
1317//----------------------------------------------------------------------------
1318// Objective-C declarations
1319//----------------------------------------------------------------------------
1320
1321void DeclPrinter::PrintObjCMethodType(ASTContext &Ctx,
1323 QualType T) {
1324 Out << '(';
1326 Out << "in ";
1328 Out << "inout ";
1330 Out << "out ";
1332 Out << "bycopy ";
1334 Out << "byref ";
1336 Out << "oneway ";
1338 if (auto nullability = AttributedType::stripOuterNullability(T))
1339 Out << getNullabilitySpelling(*nullability, true) << ' ';
1340 }
1341
1342 Out << Ctx.getUnqualifiedObjCPointerType(T).getAsString(Policy);
1343 Out << ')';
1344}
1345
1346void DeclPrinter::PrintObjCTypeParams(ObjCTypeParamList *Params) {
1347 Out << "<";
1348 unsigned First = true;
1349 for (auto *Param : *Params) {
1350 if (First) {
1351 First = false;
1352 } else {
1353 Out << ", ";
1354 }
1355
1356 switch (Param->getVariance()) {
1358 break;
1359
1361 Out << "__covariant ";
1362 break;
1363
1365 Out << "__contravariant ";
1366 break;
1367 }
1368
1369 Out << Param->getDeclName();
1370
1371 if (Param->hasExplicitBound()) {
1372 Out << " : " << Param->getUnderlyingType().getAsString(Policy);
1373 }
1374 }
1375 Out << ">";
1376}
1377
1378void DeclPrinter::VisitObjCMethodDecl(ObjCMethodDecl *OMD) {
1379 if (OMD->isInstanceMethod())
1380 Out << "- ";
1381 else
1382 Out << "+ ";
1383 if (!OMD->getReturnType().isNull()) {
1384 PrintObjCMethodType(OMD->getASTContext(), OMD->getObjCDeclQualifier(),
1385 OMD->getReturnType());
1386 }
1387
1388 std::string name = OMD->getSelector().getAsString();
1389 std::string::size_type pos, lastPos = 0;
1390 for (const auto *PI : OMD->parameters()) {
1391 // FIXME: selector is missing here!
1392 pos = name.find_first_of(':', lastPos);
1393 if (lastPos != 0)
1394 Out << " ";
1395 Out << name.substr(lastPos, pos - lastPos) << ':';
1396 PrintObjCMethodType(OMD->getASTContext(),
1397 PI->getObjCDeclQualifier(),
1398 PI->getType());
1399 Out << *PI;
1400 lastPos = pos + 1;
1401 }
1402
1403 if (OMD->param_begin() == OMD->param_end())
1404 Out << name;
1405
1406 if (OMD->isVariadic())
1407 Out << ", ...";
1408
1409 prettyPrintAttributes(OMD);
1410
1411 if (OMD->getBody() && !Policy.TerseOutput) {
1412 Out << ' ';
1413 OMD->getBody()->printPretty(Out, nullptr, Policy, Indentation, "\n",
1414 &Context);
1415 }
1416 else if (Policy.PolishForDeclaration)
1417 Out << ';';
1418}
1419
1420void DeclPrinter::VisitObjCImplementationDecl(ObjCImplementationDecl *OID) {
1421 std::string I = OID->getNameAsString();
1422 ObjCInterfaceDecl *SID = OID->getSuperClass();
1423
1424 bool eolnOut = false;
1425 if (SID)
1426 Out << "@implementation " << I << " : " << *SID;
1427 else
1428 Out << "@implementation " << I;
1429
1430 if (OID->ivar_size() > 0) {
1431 Out << "{\n";
1432 eolnOut = true;
1433 Indentation += Policy.Indentation;
1434 for (const auto *I : OID->ivars()) {
1435 Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
1436 getAsString(Policy) << ' ' << *I << ";\n";
1437 }
1438 Indentation -= Policy.Indentation;
1439 Out << "}\n";
1440 }
1441 else if (SID || (OID->decls_begin() != OID->decls_end())) {
1442 Out << "\n";
1443 eolnOut = true;
1444 }
1445 VisitDeclContext(OID, false);
1446 if (!eolnOut)
1447 Out << "\n";
1448 Out << "@end";
1449}
1450
1451void DeclPrinter::VisitObjCInterfaceDecl(ObjCInterfaceDecl *OID) {
1452 std::string I = OID->getNameAsString();
1453 ObjCInterfaceDecl *SID = OID->getSuperClass();
1454
1455 if (!OID->isThisDeclarationADefinition()) {
1456 Out << "@class " << I;
1457
1458 if (auto TypeParams = OID->getTypeParamListAsWritten()) {
1459 PrintObjCTypeParams(TypeParams);
1460 }
1461
1462 Out << ";";
1463 return;
1464 }
1465 bool eolnOut = false;
1466 if (OID->hasAttrs()) {
1467 prettyPrintAttributes(OID);
1468 Out << "\n";
1469 }
1470
1471 Out << "@interface " << I;
1472
1473 if (auto TypeParams = OID->getTypeParamListAsWritten()) {
1474 PrintObjCTypeParams(TypeParams);
1475 }
1476
1477 if (SID)
1478 Out << " : " << QualType(OID->getSuperClassType(), 0).getAsString(Policy);
1479
1480 // Protocols?
1481 const ObjCList<ObjCProtocolDecl> &Protocols = OID->getReferencedProtocols();
1482 if (!Protocols.empty()) {
1483 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
1484 E = Protocols.end(); I != E; ++I)
1485 Out << (I == Protocols.begin() ? '<' : ',') << **I;
1486 Out << "> ";
1487 }
1488
1489 if (OID->ivar_size() > 0) {
1490 Out << "{\n";
1491 eolnOut = true;
1492 Indentation += Policy.Indentation;
1493 for (const auto *I : OID->ivars()) {
1494 Indent() << I->getASTContext()
1495 .getUnqualifiedObjCPointerType(I->getType())
1496 .getAsString(Policy) << ' ' << *I << ";\n";
1497 }
1498 Indentation -= Policy.Indentation;
1499 Out << "}\n";
1500 }
1501 else if (SID || (OID->decls_begin() != OID->decls_end())) {
1502 Out << "\n";
1503 eolnOut = true;
1504 }
1505
1506 VisitDeclContext(OID, false);
1507 if (!eolnOut)
1508 Out << "\n";
1509 Out << "@end";
1510 // FIXME: implement the rest...
1511}
1512
1513void DeclPrinter::VisitObjCProtocolDecl(ObjCProtocolDecl *PID) {
1514 if (!PID->isThisDeclarationADefinition()) {
1515 Out << "@protocol " << *PID << ";\n";
1516 return;
1517 }
1518 // Protocols?
1519 const ObjCList<ObjCProtocolDecl> &Protocols = PID->getReferencedProtocols();
1520 if (!Protocols.empty()) {
1521 Out << "@protocol " << *PID;
1522 for (ObjCList<ObjCProtocolDecl>::iterator I = Protocols.begin(),
1523 E = Protocols.end(); I != E; ++I)
1524 Out << (I == Protocols.begin() ? '<' : ',') << **I;
1525 Out << ">\n";
1526 } else
1527 Out << "@protocol " << *PID << '\n';
1528 VisitDeclContext(PID, false);
1529 Out << "@end";
1530}
1531
1532void DeclPrinter::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *PID) {
1533 Out << "@implementation ";
1534 if (const auto *CID = PID->getClassInterface())
1535 Out << *CID;
1536 else
1537 Out << "<<error-type>>";
1538 Out << '(' << *PID << ")\n";
1539
1540 VisitDeclContext(PID, false);
1541 Out << "@end";
1542 // FIXME: implement the rest...
1543}
1544
1545void DeclPrinter::VisitObjCCategoryDecl(ObjCCategoryDecl *PID) {
1546 Out << "@interface ";
1547 if (const auto *CID = PID->getClassInterface())
1548 Out << *CID;
1549 else
1550 Out << "<<error-type>>";
1551 if (auto TypeParams = PID->getTypeParamList()) {
1552 PrintObjCTypeParams(TypeParams);
1553 }
1554 Out << "(" << *PID << ")\n";
1555 if (PID->ivar_size() > 0) {
1556 Out << "{\n";
1557 Indentation += Policy.Indentation;
1558 for (const auto *I : PID->ivars())
1559 Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
1560 getAsString(Policy) << ' ' << *I << ";\n";
1561 Indentation -= Policy.Indentation;
1562 Out << "}\n";
1563 }
1564
1565 VisitDeclContext(PID, false);
1566 Out << "@end";
1567
1568 // FIXME: implement the rest...
1569}
1570
1571void DeclPrinter::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *AID) {
1572 Out << "@compatibility_alias " << *AID
1573 << ' ' << *AID->getClassInterface() << ";\n";
1574}
1575
1576/// PrintObjCPropertyDecl - print a property declaration.
1577///
1578/// Print attributes in the following order:
1579/// - class
1580/// - nonatomic | atomic
1581/// - assign | retain | strong | copy | weak | unsafe_unretained
1582/// - readwrite | readonly
1583/// - getter & setter
1584/// - nullability
1585void DeclPrinter::VisitObjCPropertyDecl(ObjCPropertyDecl *PDecl) {
1587 Out << "@required\n";
1589 Out << "@optional\n";
1590
1591 QualType T = PDecl->getType();
1592
1593 Out << "@property";
1595 bool first = true;
1596 Out << "(";
1598 Out << (first ? "" : ", ") << "class";
1599 first = false;
1600 }
1601
1603 Out << (first ? "" : ", ") << "direct";
1604 first = false;
1605 }
1606
1607 if (PDecl->getPropertyAttributes() &
1609 Out << (first ? "" : ", ") << "nonatomic";
1610 first = false;
1611 }
1613 Out << (first ? "" : ", ") << "atomic";
1614 first = false;
1615 }
1616
1618 Out << (first ? "" : ", ") << "assign";
1619 first = false;
1620 }
1622 Out << (first ? "" : ", ") << "retain";
1623 first = false;
1624 }
1625
1627 Out << (first ? "" : ", ") << "strong";
1628 first = false;
1629 }
1631 Out << (first ? "" : ", ") << "copy";
1632 first = false;
1633 }
1635 Out << (first ? "" : ", ") << "weak";
1636 first = false;
1637 }
1638 if (PDecl->getPropertyAttributes() &
1640 Out << (first ? "" : ", ") << "unsafe_unretained";
1641 first = false;
1642 }
1643
1644 if (PDecl->getPropertyAttributes() &
1646 Out << (first ? "" : ", ") << "readwrite";
1647 first = false;
1648 }
1650 Out << (first ? "" : ", ") << "readonly";
1651 first = false;
1652 }
1653
1655 Out << (first ? "" : ", ") << "getter = ";
1656 PDecl->getGetterName().print(Out);
1657 first = false;
1658 }
1660 Out << (first ? "" : ", ") << "setter = ";
1661 PDecl->getSetterName().print(Out);
1662 first = false;
1663 }
1664
1665 if (PDecl->getPropertyAttributes() &
1667 if (auto nullability = AttributedType::stripOuterNullability(T)) {
1668 if (*nullability == NullabilityKind::Unspecified &&
1669 (PDecl->getPropertyAttributes() &
1671 Out << (first ? "" : ", ") << "null_resettable";
1672 } else {
1673 Out << (first ? "" : ", ")
1674 << getNullabilitySpelling(*nullability, true);
1675 }
1676 first = false;
1677 }
1678 }
1679
1680 (void) first; // Silence dead store warning due to idiomatic code.
1681 Out << ")";
1682 }
1683 std::string TypeStr = PDecl->getASTContext().getUnqualifiedObjCPointerType(T).
1684 getAsString(Policy);
1685 Out << ' ' << TypeStr;
1686 if (!StringRef(TypeStr).ends_with("*"))
1687 Out << ' ';
1688 Out << *PDecl;
1689 if (Policy.PolishForDeclaration)
1690 Out << ';';
1691}
1692
1693void DeclPrinter::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *PID) {
1695 Out << "@synthesize ";
1696 else
1697 Out << "@dynamic ";
1698 Out << *PID->getPropertyDecl();
1699 if (PID->getPropertyIvarDecl())
1700 Out << '=' << *PID->getPropertyIvarDecl();
1701}
1702
1703void DeclPrinter::VisitUsingDecl(UsingDecl *D) {
1704 if (!D->isAccessDeclaration())
1705 Out << "using ";
1706 if (D->hasTypename())
1707 Out << "typename ";
1708 D->getQualifier()->print(Out, Policy);
1709
1710 // Use the correct record name when the using declaration is used for
1711 // inheriting constructors.
1712 for (const auto *Shadow : D->shadows()) {
1713 if (const auto *ConstructorShadow =
1714 dyn_cast<ConstructorUsingShadowDecl>(Shadow)) {
1715 assert(Shadow->getDeclContext() == ConstructorShadow->getDeclContext());
1716 Out << *ConstructorShadow->getNominatedBaseClass();
1717 return;
1718 }
1719 }
1720 Out << *D;
1721}
1722
1723void DeclPrinter::VisitUsingEnumDecl(UsingEnumDecl *D) {
1724 Out << "using enum " << D->getEnumDecl();
1725}
1726
1727void
1728DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
1729 Out << "using typename ";
1730 D->getQualifier()->print(Out, Policy);
1731 Out << D->getDeclName();
1732}
1733
1734void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
1735 if (!D->isAccessDeclaration())
1736 Out << "using ";
1737 D->getQualifier()->print(Out, Policy);
1738 Out << D->getDeclName();
1739}
1740
1741void DeclPrinter::VisitUsingShadowDecl(UsingShadowDecl *D) {
1742 // ignore
1743}
1744
1745void DeclPrinter::VisitOMPThreadPrivateDecl(OMPThreadPrivateDecl *D) {
1746 Out << "#pragma omp threadprivate";
1747 if (!D->varlist_empty()) {
1749 E = D->varlist_end();
1750 I != E; ++I) {
1751 Out << (I == D->varlist_begin() ? '(' : ',');
1752 NamedDecl *ND = cast<DeclRefExpr>(*I)->getDecl();
1753 ND->printQualifiedName(Out);
1754 }
1755 Out << ")";
1756 }
1757}
1758
1759void DeclPrinter::VisitHLSLBufferDecl(HLSLBufferDecl *D) {
1760 if (D->isCBuffer())
1761 Out << "cbuffer ";
1762 else
1763 Out << "tbuffer ";
1764
1765 Out << *D;
1766
1767 prettyPrintAttributes(D);
1768
1769 Out << " {\n";
1770 VisitDeclContext(D);
1771 Indent() << "}";
1772}
1773
1774void DeclPrinter::VisitOMPAllocateDecl(OMPAllocateDecl *D) {
1775 Out << "#pragma omp allocate";
1776 if (!D->varlist_empty()) {
1778 E = D->varlist_end();
1779 I != E; ++I) {
1780 Out << (I == D->varlist_begin() ? '(' : ',');
1781 NamedDecl *ND = cast<DeclRefExpr>(*I)->getDecl();
1782 ND->printQualifiedName(Out);
1783 }
1784 Out << ")";
1785 }
1786 if (!D->clauselist_empty()) {
1787 OMPClausePrinter Printer(Out, Policy);
1788 for (OMPClause *C : D->clauselists()) {
1789 Out << " ";
1790 Printer.Visit(C);
1791 }
1792 }
1793}
1794
1795void DeclPrinter::VisitOMPRequiresDecl(OMPRequiresDecl *D) {
1796 Out << "#pragma omp requires ";
1797 if (!D->clauselist_empty()) {
1798 OMPClausePrinter Printer(Out, Policy);
1799 for (auto I = D->clauselist_begin(), E = D->clauselist_end(); I != E; ++I)
1800 Printer.Visit(*I);
1801 }
1802}
1803
1804void DeclPrinter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
1805 if (!D->isInvalidDecl()) {
1806 Out << "#pragma omp declare reduction (";
1808 const char *OpName =
1810 assert(OpName && "not an overloaded operator");
1811 Out << OpName;
1812 } else {
1813 assert(D->getDeclName().isIdentifier());
1814 D->printName(Out, Policy);
1815 }
1816 Out << " : ";
1817 D->getType().print(Out, Policy);
1818 Out << " : ";
1819 D->getCombiner()->printPretty(Out, nullptr, Policy, 0, "\n", &Context);
1820 Out << ")";
1821 if (auto *Init = D->getInitializer()) {
1822 Out << " initializer(";
1823 switch (D->getInitializerKind()) {
1825 Out << "omp_priv(";
1826 break;
1828 Out << "omp_priv = ";
1829 break;
1831 break;
1832 }
1833 Init->printPretty(Out, nullptr, Policy, 0, "\n", &Context);
1835 Out << ")";
1836 Out << ")";
1837 }
1838 }
1839}
1840
1841void DeclPrinter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
1842 if (!D->isInvalidDecl()) {
1843 Out << "#pragma omp declare mapper (";
1844 D->printName(Out, Policy);
1845 Out << " : ";
1846 D->getType().print(Out, Policy);
1847 Out << " ";
1848 Out << D->getVarName();
1849 Out << ")";
1850 if (!D->clauselist_empty()) {
1851 OMPClausePrinter Printer(Out, Policy);
1852 for (auto *C : D->clauselists()) {
1853 Out << " ";
1854 Printer.Visit(C);
1855 }
1856 }
1857 }
1858}
1859
1860void DeclPrinter::VisitOMPCapturedExprDecl(OMPCapturedExprDecl *D) {
1861 D->getInit()->printPretty(Out, nullptr, Policy, Indentation, "\n", &Context);
1862}
1863
1864void DeclPrinter::VisitTemplateTypeParmDecl(const TemplateTypeParmDecl *TTP) {
1865 if (const TypeConstraint *TC = TTP->getTypeConstraint())
1866 TC->print(Out, Policy);
1867 else if (TTP->wasDeclaredWithTypename())
1868 Out << "typename";
1869 else
1870 Out << "class";
1871
1872 if (TTP->isParameterPack())
1873 Out << " ...";
1874 else if (TTP->getDeclName())
1875 Out << ' ';
1876
1877 if (TTP->getDeclName()) {
1878 if (Policy.CleanUglifiedParameters && TTP->getIdentifier())
1879 Out << TTP->getIdentifier()->deuglifiedName();
1880 else
1881 Out << TTP->getDeclName();
1882 }
1883
1884 if (TTP->hasDefaultArgument()) {
1885 Out << " = ";
1886 Out << TTP->getDefaultArgument().getAsString(Policy);
1887 }
1888}
1889
1890void DeclPrinter::VisitNonTypeTemplateParmDecl(
1891 const NonTypeTemplateParmDecl *NTTP) {
1892 StringRef Name;
1893 if (IdentifierInfo *II = NTTP->getIdentifier())
1894 Name =
1895 Policy.CleanUglifiedParameters ? II->deuglifiedName() : II->getName();
1896 printDeclType(NTTP->getType(), Name, NTTP->isParameterPack());
1897
1898 if (NTTP->hasDefaultArgument()) {
1899 Out << " = ";
1900 NTTP->getDefaultArgument()->printPretty(Out, nullptr, Policy, Indentation,
1901 "\n", &Context);
1902 }
1903}
Defines the clang::ASTContext interface.
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:182
const LangOptions & getLangOpts() const
Definition: ASTContext.h:775
const clang::PrintingPolicy & getPrintingPolicy() const
Definition: ASTContext.h:697
QualType getUnqualifiedObjCPointerType(QualType type) const
getUnqualifiedObjCPointerType - Returns version of Objective-C pointer type with lifetime qualifier r...
Definition: ASTContext.h:2191
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Definition: Type.h:3518
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:4789
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Definition: Type.h:5981
shadow_range shadows() const
Definition: DeclCXX.h:3483
Pointer to a block type.
Definition: Type.h:3349
Represents a base class of a C++ class.
Definition: DeclCXX.h:146
Represents a call to a C++ constructor.
Definition: ExprCXX.h:1540
Represents a C++ constructor within a class.
Definition: DeclCXX.h:2535
Represents a C++ conversion function within a class.
Definition: DeclCXX.h:2862
Represents a C++ deduction guide declaration.
Definition: DeclCXX.h:1952
TemplateDecl * getDeducedTemplate() const
Get the template for which this guide performs deduction.
Definition: DeclCXX.h:1994
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:2279
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:2066
bool isTranslationUnit() const
Definition: DeclBase.h:2142
void dumpDeclContext() const
decl_iterator decls_end() const
Definition: DeclBase.h:2324
decl_iterator decls_begin() const
Definition: DeclBase.cpp:1556
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 hasAttrs() const
Definition: DeclBase.h:524
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:599
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:594
SourceLocation getLocation() const
Definition: DeclBase.h:445
static void printGroup(Decl **Begin, unsigned NumDecls, raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation=0)
AccessSpecifier getAccess() const
Definition: DeclBase.h:513
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
AttrVec & getAttrs()
Definition: DeclBase.h:530
bool hasAttr() const
Definition: DeclBase.h:583
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:828
TemplateParameterList * getTemplateParameterList(unsigned index) const
Definition: Decl.h:862
unsigned getNumTemplateParameterLists() const
Definition: Decl.h:858
Expr * getTrailingRequiresClause()
Get the constraint-expression introduced by the trailing requires-clause in the function/member decla...
Definition: Decl.h:846
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:799
Represents an empty-declaration.
Definition: Decl.h:4926
An instance of this object exists for each enum constant that is defined.
Definition: Decl.h:3298
const Expr * getInitExpr() const
Definition: Decl.h:3316
Represents an enum.
Definition: Decl.h:3868
bool isScoped() const
Returns true if this is a C++11 scoped enumeration.
Definition: Decl.h:4073
bool isScopedUsingClassTag() const
Returns true if this is a C++11 scoped enumeration.
Definition: Decl.h:4076
bool isFixed() const
Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...
Definition: Decl.h:4082
QualType getIntegerType() const
Return the integer type this enum decl corresponds to.
Definition: Decl.h:4028
Store information needed for an explicit specifier.
Definition: DeclCXX.h:1897
const Expr * getExpr() const
Definition: DeclCXX.h:1906
static ExplicitSpecifier getFromDecl(FunctionDecl *Function)
Definition: DeclCXX.cpp:2144
bool isSpecified() const
Determine if the declaration had an explicit specifier of any kind.
Definition: DeclCXX.h:1910
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
Definition: ExprCXX.h:3443
This represents one expression.
Definition: Expr.h:110
bool isDefaultArgument() const
Determine whether this expression is a default function argument.
Definition: Expr.cpp:3154
Represents a member of a struct/union/class.
Definition: Decl.h:3058
bool isMutable() const
Determines whether this field is mutable (C++ only).
Definition: Decl.h:3146
Expr * getInClassInitializer() const
Get the C++11 default member initializer for this member, or null if one has not been set.
Definition: Decl.cpp:4572
bool isBitField() const
Determines whether this field is a bitfield.
Definition: Decl.h:3149
InClassInitStyle getInClassInitStyle() const
Get the kind of (C++11) default member initializer that this field has.
Definition: Decl.h:3213
Expr * getBitWidth() const
Returns the expression that represents the bit width, if this field is a bit field.
Definition: Decl.h:3162
const StringLiteral * getAsmString() const
Definition: Decl.h:4445
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:1971
const ParmVarDecl * getParamDecl(unsigned i) const
Definition: Decl.h:2707
Stmt * getBody(const FunctionDecl *&Definition) const
Retrieve the body (definition) of the function.
Definition: Decl.cpp:3236
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
Definition: Decl.cpp:4054
FunctionTemplateDecl * getDescribedFunctionTemplate() const
Retrieves the function template that is described by this function declaration.
Definition: Decl.cpp:4042
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
Definition: Decl.h:2284
bool isImmediateFunction() const
Definition: Decl.cpp:3288
StringLiteral * getDeletedMessage() const
Get the message that indicates why this function was deleted.
Definition: Decl.h:2668
bool isExplicitlyDefaulted() const
Whether this function is explicitly defaulted.
Definition: Decl.h:2352
bool hasWrittenPrototype() const
Whether this function has a written prototype.
Definition: Decl.h:2411
bool hasPrototype() const
Whether this function has a prototype, either because one was explicitly written or because it was "i...
Definition: Decl.h:2406
bool doesThisDeclarationHaveABody() const
Returns whether this specific declaration of the function has a body.
Definition: Decl.h:2296
bool isConstexprSpecified() const
Definition: Decl.h:2442
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
Definition: Decl.cpp:4178
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Definition: Decl.h:2798
bool isDeletedAsWritten() const
Definition: Decl.h:2507
bool isPureVirtual() const
Whether this virtual function is pure, i.e.
Definition: Decl.h:2323
bool isConsteval() const
Definition: Decl.h:2445
bool isVirtualAsWritten() const
Whether this function is marked as virtual explicitly.
Definition: Decl.h:2314
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
Definition: Decl.cpp:3692
DeclarationNameInfo getNameInfo() const
Definition: Decl.h:2183
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:3203
bool isInlineSpecified() const
Determine whether the "inline" keyword was specified for this function.
Definition: Decl.h:2809
const ASTTemplateArgumentListInfo * getTemplateSpecializationArgsAsWritten() const
Retrieve the template argument list as written in the sources, if any.
Definition: Decl.cpp:4188
Represents a prototype with parameter type info, e.g.
Definition: Type.h:4656
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
Definition: Type.h:4915
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
Definition: Type.h:5028
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
Definition: Type.h:4966
unsigned getNumExceptions() const
Return the number of types in the exception specification.
Definition: Type.h:4958
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
Definition: Type.h:4924
bool isVariadic() const
Whether this function prototype is variadic.
Definition: Type.h:5012
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
Definition: Type.h:4973
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Definition: Type.h:5038
Declaration of a template function.
Definition: DeclTemplate.h:958
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:4256
bool isConst() const
Definition: Type.h:4591
bool isRestrict() const
Definition: Type.h:4593
bool isVolatile() const
Definition: Type.h:4592
HLSLBufferDecl - Represent a cbuffer or tbuffer declaration.
Definition: Decl.h:4941
bool isCBuffer() const
Definition: Decl.h:4969
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:4800
Module * getImportedModule() const
Retrieve the module that was imported by the import declaration.
Definition: Decl.h:4858
Represents the declaration of a label.
Definition: Decl.h:499
Represents a linkage specification.
Definition: DeclCXX.h:2934
LinkageSpecLanguageIDs getLanguage() const
Return the language specified by this linkage specification.
Definition: DeclCXX.h:2957
bool hasBraces() const
Determines whether this linkage specification had braces in its syntactic form.
Definition: DeclCXX.h:2968
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:244
This represents a decl that may have a name.
Definition: Decl.h:249
bool isModulePrivate() const
Whether this declaration was marked as being private to the module in which it was defined.
Definition: DeclBase.h:648
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
Definition: Decl.h:270
StringRef getName() const
Get the name of identifier for this declaration as a StringRef.
Definition: Decl.h:276
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
Definition: Decl.h:315
std::string getQualifiedNameAsString() const
Definition: Decl.cpp:1683
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:1690
virtual void printName(raw_ostream &OS, const PrintingPolicy &Policy) const
Pretty-print the unqualified name of this declaration.
Definition: Decl.cpp:1675
Represents a C++ namespace alias.
Definition: DeclCXX.h:3120
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of the namespace.
Definition: DeclCXX.h:3187
NamedDecl * getAliasedNamespace() const
Retrieve the namespace that this alias refers to, which may either be a NamespaceDecl or a NamespaceA...
Definition: DeclCXX.h:3215
Represent a C++ namespace.
Definition: Decl.h:547
bool isInline() const
Returns true if this is an inline namespace declaration.
Definition: Decl.h:610
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:474
bool varlist_empty() const
Definition: DeclOpenMP.h:512
bool clauselist_empty() const
Definition: DeclOpenMP.h:514
varlist_iterator varlist_begin()
Definition: DeclOpenMP.h:522
MutableArrayRef< Expr * >::iterator varlist_iterator
Definition: DeclOpenMP.h:502
clauselist_range clauselists()
Definition: DeclOpenMP.h:527
varlist_iterator varlist_end()
Definition: DeclOpenMP.h:523
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:417
clauselist_iterator clauselist_begin()
Definition: DeclOpenMP.h:448
bool clauselist_empty() const
Definition: DeclOpenMP.h:440
clauselist_iterator clauselist_end()
Definition: DeclOpenMP.h:449
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:2326
ObjCInterfaceDecl * getClassInterface()
Definition: DeclObjC.h:2369
ObjCTypeParamList * getTypeParamList() const
Retrieve the type parameter list associated with this category or extension.
Definition: DeclObjC.h:2374
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:2594
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: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:7008
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:2802
ObjCIvarDecl * getPropertyIvarDecl() const
Definition: DeclObjC.h:2876
Kind getPropertyImplementation() const
Definition: DeclObjC.h:2872
ObjCPropertyDecl * getPropertyDecl() const
Definition: DeclObjC.h:2867
Represents an Objective-C protocol declaration.
Definition: DeclObjC.h:2082
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
Definition: DeclObjC.h:2258
const ObjCProtocolList & getReferencedProtocols() const
Definition: DeclObjC.h:2150
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:6569
Sugar for parentheses used when specifying types.
Definition: Type.h:3113
Represents a parameter to a function.
Definition: Decl.h:1761
PointerType - C99 6.7.5.1 - Pointer Declarators.
Definition: Type.h:3139
A (possibly-)qualified type.
Definition: Type.h:940
bool isNull() const
Return true if this QualType doesn't point to a type yet.
Definition: Type.h:1007
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
StreamedQualTypeHelper stream(const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
Definition: Type.h:1383
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Definition: Type.h:1327
Represents a struct/union/class.
Definition: Decl.h:4169
Base for LValueReferenceType and RValueReferenceType.
Definition: Type.h:3380
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:4058
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:1773
Represents the declaration of a struct/union/class/enum.
Definition: Decl.h:3585
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of this declaration, if it was present in ...
Definition: Decl.h:3822
StringRef getKindName() const
Definition: Decl.h:3776
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
Definition: Decl.h:3688
A template argument list.
Definition: DeclTemplate.h:244
The base class of all kinds of template declarations (e.g., class, function, etc.).
Definition: DeclTemplate.h:394
NamedDecl * getTemplatedDecl() const
Get the underlying, templated declaration.
Definition: DeclTemplate.h:426
TemplateParameterList * getTemplateParameters() const
Get the list of template parameters.
Definition: DeclTemplate.h:413
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.
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:4458
The top declaration context.
Definition: Decl.h:84
Represents the declaration of a typedef-name via a C++11 alias-declaration.
Definition: Decl.h:3556
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:7330
QualType getType() const
Return the type wrapped by this type source info.
Definition: Type.h:7341
bool isStructureType() const
Definition: Type.cpp:628
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
Definition: Type.cpp:694
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:622
const T * getAs() const
Member-template getAs<specific type>'.
Definition: Type.h:8123
bool isUnionType() const
Definition: Type.cpp:660
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Definition: Decl.h:3535
Base class for declarations which introduce a typedef-name.
Definition: Decl.h:3433
TypeSourceInfo * getTypeSourceInfo() const
Definition: Decl.h:3483
Represents a dependent using declaration which was marked with typename.
Definition: DeclCXX.h:3959
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name.
Definition: DeclCXX.h:3996
Represents a dependent using declaration which was not marked with typename.
Definition: DeclCXX.h:3862
bool isAccessDeclaration() const
Return true if it is a C++03 access declaration (no 'using').
Definition: DeclCXX.h:3899
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name.
Definition: DeclCXX.h:3906
Represents a C++ using-declaration.
Definition: DeclCXX.h:3512
bool hasTypename() const
Return true if the using declaration has 'typename'.
Definition: DeclCXX.h:3561
bool isAccessDeclaration() const
Return true if it is a C++03 access declaration (no 'using').
Definition: DeclCXX.h:3558
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name.
Definition: DeclCXX.h:3549
Represents C++ using-directive.
Definition: DeclCXX.h:3015
NestedNameSpecifier * getQualifier() const
Retrieve the nested-name-specifier that qualifies the name of the namespace.
Definition: DeclCXX.h:3064
NamedDecl * getNominatedNamespaceAsWritten()
Definition: DeclCXX.h:3068
Represents a C++ using-enum-declaration.
Definition: DeclCXX.h:3713
EnumDecl * getEnumDecl() const
Definition: DeclCXX.h:3757
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Definition: DeclCXX.h:3320
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Definition: Decl.h:706
QualType getType() const
Definition: Decl.h:717
Represents a variable declaration or definition.
Definition: Decl.h:918
bool isConstexpr() const
Whether this variable is (C++11) constexpr.
Definition: Decl.h:1549
InitializationStyle getInitStyle() const
The style of initialization for this declaration.
Definition: Decl.h:1446
static const char * getStorageClassSpecifierString(StorageClass SC)
Return the string used to specify the storage class SC.
Definition: Decl.cpp:2118
@ CInit
C-style initialization with assignment.
Definition: Decl.h:923
@ CallInit
Call-style initialization (C++98)
Definition: Decl.h:926
bool isCXXForRangeDecl() const
Determine whether this variable is the for-range-declaration in a C++0x for-range statement.
Definition: Decl.h:1502
ThreadStorageClassSpecifier getTSCSpec() const
Definition: Decl.h:1164
const Expr * getInit() const
Definition: Decl.h:1355
StorageClass getStorageClass() const
Returns the storage class as written in the source.
Definition: Decl.h:1155
Represents a GCC generic vector type.
Definition: Type.h:3969
@ 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:398
@ Unspecified
Whether values of this type can be null is (explicitly) unspecified.
@ ICIS_ListInit
Direct list-initialization.
Definition: Specifiers.h:271
@ RQ_None
No ref-qualifier was provided.
Definition: Type.h:1762
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
Definition: Type.h:1765
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
Definition: Type.h:1768
StorageClass
Storage classes.
Definition: Specifiers.h:245
@ SC_Auto
Definition: Specifiers.h:253
@ SC_PrivateExtern
Definition: Specifiers.h:250
@ SC_Extern
Definition: Specifiers.h:248
@ SC_Register
Definition: Specifiers.h:254
@ SC_Static
Definition: Specifiers.h:249
@ SC_None
Definition: Specifiers.h:247
@ TSCS_thread_local
C++11 thread_local.
Definition: Specifiers.h:238
@ TSCS_unspecified
Definition: Specifiers.h:233
@ TSCS__Thread_local
C11 _Thread_local.
Definition: Specifiers.h:241
@ TSCS___thread
GNU __thread.
Definition: Specifiers.h:235
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:191
@ 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:120
@ AS_none
Definition: Specifiers.h:124
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 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.