25#include "llvm/Support/raw_ostream.h"
29 class DeclPrinter :
public DeclVisitor<DeclPrinter> {
34 bool PrintInstantiation;
36 raw_ostream& Indent() {
return Indent(Indentation); }
37 raw_ostream& Indent(
unsigned Indentation);
52 void PrintOpenACCRoutineOnLambda(
Decl *
D);
56 const ASTContext &Context,
unsigned Indentation = 0,
57 bool PrintInstantiation =
false)
58 : Out(Out), Policy(Policy), Context(Context), Indentation(Indentation),
59 PrintInstantiation(PrintInstantiation) {}
61 void VisitDeclContext(
DeclContext *DC,
bool Indent =
true);
88 void VisitClassTemplateSpecializationDecl(
90 void VisitClassTemplatePartialSpecializationDecl(
120 bool OmitTemplateKW =
false);
127 prettyPrintAttributes(
const Decl *
D,
128 AttrPosAsWritten Pos = AttrPosAsWritten::Default);
129 void prettyPrintPragmas(
Decl *
D);
130 void printDeclType(
QualType T, StringRef DeclName,
bool Pack =
false);
135 bool PrintInstantiation)
const {
140 unsigned Indentation,
bool PrintInstantiation)
const {
141 DeclPrinter Printer(Out, Policy,
getASTContext(), Indentation,
143 Printer.Visit(
const_cast<Decl*
>(
this));
147 bool OmitTemplateKW)
const {
153 bool OmitTemplateKW)
const {
154 DeclPrinter Printer(Out, Policy, Context);
155 Printer.printTemplateParameters(
this, OmitTemplateKW);
169 else if (
const ArrayType *ATy = dyn_cast<ArrayType>(BaseType))
170 BaseType = ATy->getElementType();
172 BaseType = FTy->getReturnType();
174 BaseType = VTy->getElementType();
178 BaseType = ATy->getDeducedType();
180 BaseType = PTy->desugar();
190 return TDD->getUnderlyingType();
192 return VD->getType();
198 unsigned Indentation) {
200 (*Begin)->print(Out, Policy, Indentation);
205 if (isa<TagDecl>(*
Begin))
219 (*Begin)->print(Out, SubPolicy, Indentation);
229 ASTContext &Ctx = cast<TranslationUnitDecl>(DC)->getASTContext();
231 Printer.VisitDeclContext(
const_cast<DeclContext *
>(
this),
false);
234raw_ostream& DeclPrinter::Indent(
unsigned Indentation) {
235 for (
unsigned i = 0; i != Indentation; ++i)
246 return DeclPrinter::AttrPosAsWritten::Left;
248 if (
C.getSourceManager().isBeforeInTranslationUnit(ALoc, DLoc))
249 return DeclPrinter::AttrPosAsWritten::Left;
251 return DeclPrinter::AttrPosAsWritten::Right;
255bool DeclPrinter::prettyPrintAttributes(
const Decl *
D,
256 AttrPosAsWritten Pos ) {
257 bool hasPrinted =
false;
261 for (
auto *A : Attrs) {
262 if (A->isInherited() || A->isImplicit())
267 switch (A->getKind()) {
269#define PRAGMA_SPELLING_ATTR(X) case attr::X:
270#include "clang/Basic/AttrList.inc"
274 assert(APos != AttrPosAsWritten::Default &&
275 "Default not a valid for an attribute location");
276 if (Pos == AttrPosAsWritten::Default || Pos == APos) {
277 if (Pos != AttrPosAsWritten::Left)
279 A->printPretty(Out, Policy);
281 if (Pos == AttrPosAsWritten::Left)
291void DeclPrinter::PrintOpenACCRoutineOnLambda(
Decl *
D) {
293 if (
const auto *VD = dyn_cast<VarDecl>(
D)) {
294 if (
const auto *
Init = VD->getInit())
295 CXXRD =
Init->getType().isNull() ? nullptr
296 :
Init->getType()->getAsCXXRecordDecl();
297 }
else if (
const auto *FD = dyn_cast<FieldDecl>(
D)) {
299 FD->getType().isNull() ? nullptr : FD->getType()->getAsCXXRecordDecl();
306 for (
auto *A :
Call->specific_attrs<OpenACCRoutineDeclAttr>()) {
307 A->printPretty(Out, Policy);
313void DeclPrinter::prettyPrintPragmas(
Decl *
D) {
317 PrintOpenACCRoutineOnLambda(
D);
321 for (
auto *A : Attrs) {
322 switch (A->getKind()) {
324#define PRAGMA_SPELLING_ATTR(X) case attr::X:
325#include "clang/Basic/AttrList.inc"
326 A->printPretty(Out, Policy);
336void DeclPrinter::printDeclType(
QualType T, StringRef DeclName,
bool Pack) {
342 T = PET->getPattern();
344 T.print(Out, Policy, (Pack ?
"..." :
"") + DeclName, Indentation);
357 if (AccessSpelling.empty())
358 llvm_unreachable(
"No access specifier!");
359 Out << AccessSpelling;
363 std::string &Proto) {
364 bool HasInitializerList =
false;
365 for (
const auto *BMInitializer : CDecl->
inits()) {
366 if (BMInitializer->isInClassMemberInitializer())
368 if (!BMInitializer->isWritten())
371 if (!HasInitializerList) {
375 HasInitializerList =
true;
379 if (BMInitializer->isAnyMemberInitializer()) {
380 FieldDecl *FD = BMInitializer->getAnyMember();
382 }
else if (BMInitializer->isDelegatingInitializer()) {
388 if (
Expr *
Init = BMInitializer->getInit()) {
389 bool OutParens = !isa<InitListExpr>(
Init);
395 Init = Tmp->getSubExpr();
399 Expr *SimpleInit =
nullptr;
400 Expr **Args =
nullptr;
401 unsigned NumArgs = 0;
403 Args = ParenList->getExprs();
404 NumArgs = ParenList->getNumExprs();
406 dyn_cast<CXXConstructExpr>(
Init)) {
407 Args = Construct->getArgs();
408 NumArgs = Construct->getNumArgs();
413 SimpleInit->
printPretty(Out,
nullptr, Policy, Indentation,
"\n",
416 for (
unsigned I = 0; I != NumArgs; ++I) {
417 assert(Args[I] !=
nullptr &&
"Expected non-null Expr");
418 if (isa<CXXDefaultArgExpr>(Args[I]))
423 Args[I]->
printPretty(Out,
nullptr, Policy, Indentation,
"\n",
434 if (BMInitializer->isPackExpansion())
443void DeclPrinter::VisitDeclContext(
DeclContext *DC,
bool Indent) {
456 if (isa<ObjCIvarDecl>(*
D))
465 if (
auto FD = dyn_cast<FunctionDecl>(*
D))
467 !isa<ClassTemplateSpecializationDecl>(DC))
483 if (!Decls.empty() && !CurDeclType.
isNull()) {
485 if (
const auto *TT = dyn_cast_or_null<TagType>(BaseType);
486 TT && TT->isTagOwned()) {
487 if (TT->getOriginalDecl() == Decls[0]) {
496 ProcessDeclGroup(Decls);
500 if (isa<TagDecl>(*
D) && !cast<TagDecl>(*D)->isFreeStanding()) {
505 if (isa<AccessSpecDecl>(*
D)) {
518 const char *Terminator =
nullptr;
519 if (isa<OMPThreadPrivateDecl>(*
D) || isa<OMPDeclareReductionDecl>(*
D) ||
520 isa<OMPDeclareMapperDecl>(*
D) || isa<OMPRequiresDecl>(*
D) ||
521 isa<OMPAllocateDecl>(*
D))
522 Terminator =
nullptr;
523 else if (isa<OpenACCDeclareDecl, OpenACCRoutineDecl>(*
D))
524 Terminator =
nullptr;
525 else if (isa<ObjCMethodDecl>(*
D) && cast<ObjCMethodDecl>(*D)->hasBody())
526 Terminator =
nullptr;
527 else if (
auto FD = dyn_cast<FunctionDecl>(*
D)) {
528 if (FD->doesThisDeclarationHaveABody() && !FD->isDefaulted())
529 Terminator =
nullptr;
532 }
else if (
auto TD = dyn_cast<FunctionTemplateDecl>(*
D)) {
533 if (TD->getTemplatedDecl()->doesThisDeclarationHaveABody())
534 Terminator =
nullptr;
540 Terminator =
nullptr;
541 else if (isa<EnumConstantDecl>(*
D)) {
552 ((isa<FunctionDecl>(*
D) &&
553 cast<FunctionDecl>(*D)->doesThisDeclarationHaveABody()) ||
554 (isa<FunctionTemplateDecl>(*
D) &&
555 cast<FunctionTemplateDecl>(*D)->getTemplatedDecl()->doesThisDeclarationHaveABody())))
562 if (
D->
hasAttr<OMPDeclareTargetDeclAttr>())
563 Out <<
"#pragma omp end declare target\n";
567 ProcessDeclGroup(Decls);
574 VisitDeclContext(
D,
false);
582 Out <<
"__module_private__ ";
584 QualType Ty =
D->getTypeSourceInfo()->getType();
585 Ty.
print(Out, Policy,
D->getName(), Indentation);
586 prettyPrintAttributes(
D);
590 Out <<
"using " << *
D;
591 prettyPrintAttributes(
D);
592 Out <<
" = " <<
D->getTypeSourceInfo()->getType().getAsString(Policy);
595void DeclPrinter::VisitEnumDecl(
EnumDecl *
D) {
597 Out <<
"__module_private__ ";
600 if (
D->isScopedUsingClassTag())
606 prettyPrintAttributes(
D);
608 if (
D->getDeclName())
609 Out <<
' ' <<
D->getDeclName();
612 Out <<
" : " <<
D->getIntegerType().stream(Policy);
614 if (
D->isCompleteDefinition()) {
623 Out <<
"__module_private__ ";
624 Out <<
D->getKindName();
626 prettyPrintAttributes(
D);
628 if (
D->getIdentifier())
631 if (
D->isCompleteDefinition()) {
640 prettyPrintAttributes(
D);
643 Init->printPretty(Out,
nullptr, Policy, Indentation,
"\n", &Context);
650 std::string Proto =
"explicit";
651 llvm::raw_string_ostream EOut(Proto);
663 if (!
D->getDescribedFunctionTemplate() &&
664 !
D->isFunctionTemplateSpecialization()) {
665 prettyPrintPragmas(
D);
666 prettyPrintAttributes(
D, AttrPosAsWritten::Left);
669 if (
D->isFunctionTemplateSpecialization())
670 Out <<
"template<> ";
671 else if (!
D->getDescribedFunctionTemplate()) {
672 for (
unsigned I = 0, NumTemplateParams =
D->getNumTemplateParameterLists();
673 I < NumTemplateParams; ++I)
674 printTemplateParameters(
D->getTemplateParameterList(I));
681 switch (
D->getStorageClass()) {
687 llvm_unreachable(
"invalid for functions");
690 if (
D->isInlineSpecified()) Out <<
"inline ";
691 if (
D->isVirtualAsWritten()) Out <<
"virtual ";
693 if (
D->isConstexprSpecified() && !
D->isExplicitlyDefaulted())
695 if (
D->isConsteval()) Out <<
"consteval ";
696 else if (
D->isImmediateFunction())
704 SubPolicy.SuppressSpecifiers =
false;
708 Proto +=
D->getQualifiedNameAsString();
710 llvm::raw_string_ostream OS(Proto);
712 D->getQualifier().
print(OS, Policy);
713 D->getNameInfo().printName(OS, Policy);
718 if (
D->isFunctionTemplateSpecialization()) {
719 llvm::raw_string_ostream POut(Proto);
720 DeclPrinter TArgPrinter(POut, SubPolicy, Context, Indentation);
721 const auto *TArgAsWritten =
D->getTemplateSpecializationArgsAsWritten();
723 TArgPrinter.printTemplateArguments(TArgAsWritten->arguments(),
nullptr);
725 D->getTemplateSpecializationArgs())
726 TArgPrinter.printTemplateArguments(TArgs->asArray(),
nullptr);
730 while (
const ParenType *PT = dyn_cast<ParenType>(Ty)) {
731 Proto =
'(' + Proto +
')';
732 Ty = PT->getInnerType();
737 if (
D->hasWrittenPrototype())
738 FT = dyn_cast<FunctionProtoType>(AFT);
742 llvm::raw_string_ostream POut(Proto);
743 DeclPrinter ParamPrinter(POut, SubPolicy, Context, Indentation);
744 for (
unsigned i = 0, e =
D->getNumParams(); i != e; ++i) {
746 ParamPrinter.VisitParmVarDecl(
D->getParamDecl(i));
750 if (
D->getNumParams()) POut <<
", ";
752 }
else if (!
D->getNumParams() && !Context.
getLangOpts().CPlusPlus) {
757 }
else if (
D->doesThisDeclarationHaveABody() && !
D->hasPrototype()) {
758 for (
unsigned i = 0, e =
D->getNumParams(); i != e; ++i) {
761 Proto +=
D->getParamDecl(i)->getNameAsString();
771 Proto +=
" volatile";
773 Proto +=
" restrict";
800 Proto +=
" noexcept";
803 llvm::raw_string_ostream EOut(Proto);
805 Indentation,
"\n", &Context);
812 PrintConstructorInitializers(CDecl, Proto);
813 }
else if (!ConversionDecl && !isa<CXXDestructorDecl>(
D)) {
817 Out << Proto <<
" -> ";
820 AFT->getReturnType().print(Out, Policy, Proto);
826 D->getTrailingRequiresClause()) {
831 TrailingRequiresClause.ConstraintExpr->printPretty(
832 Out,
nullptr, SubPolicy, Indentation,
"\n", &Context);
835 Ty.
print(Out, Policy, Proto);
838 prettyPrintAttributes(
D, AttrPosAsWritten::Right);
840 if (
D->isPureVirtual())
842 else if (
D->isDeletedAsWritten()) {
846 M->outputString(Out);
849 }
else if (
D->isExplicitlyDefaulted())
851 else if (
D->doesThisDeclarationHaveABody()) {
853 if (!
D->hasPrototype() &&
D->getNumParams()) {
857 DeclPrinter ParamPrinter(Out, SubPolicy, Context, Indentation);
859 for (
unsigned i = 0, e =
D->getNumParams(); i != e; ++i) {
861 ParamPrinter.VisitParmVarDecl(
D->getParamDecl(i));
879 unsigned NumTPLists =
D->getFriendTypeNumTemplateParameterLists();
880 for (
unsigned i = 0; i < NumTPLists; ++i)
881 printTemplateParameters(
D->getFriendTypeTemplateParameterList(i));
883 Out << TSI->getType().getAsString(Policy);
886 dyn_cast<FunctionDecl>(
D->getFriendDecl())) {
888 VisitFunctionDecl(FD);
891 dyn_cast<FunctionTemplateDecl>(
D->getFriendDecl())) {
893 VisitFunctionTemplateDecl(FTD);
896 dyn_cast<ClassTemplateDecl>(
D->getFriendDecl())) {
898 VisitRedeclarableTemplateDecl(CTD);
901 if (
D->isPackExpansion())
905void DeclPrinter::VisitFieldDecl(
FieldDecl *
D) {
906 prettyPrintPragmas(
D);
911 Out <<
"__module_private__ ";
914 stream(Policy,
D->getName(), Indentation);
916 if (
D->isBitField()) {
918 D->getBitWidth()->printPretty(Out,
nullptr, Policy, Indentation,
"\n",
928 Init->printPretty(Out,
nullptr, Policy, Indentation,
"\n", &Context);
930 prettyPrintAttributes(
D);
933void DeclPrinter::VisitLabelDecl(
LabelDecl *
D) {
937void DeclPrinter::VisitVarDecl(
VarDecl *
D) {
938 prettyPrintPragmas(
D);
940 prettyPrintAttributes(
D, AttrPosAsWritten::Left);
942 if (
const auto *Param = dyn_cast<ParmVarDecl>(
D);
943 Param && Param->isExplicitObjectParameter())
947 ?
D->getTypeSourceInfo()->getType()
955 switch (
D->getTSCSpec()) {
962 Out <<
"_Thread_local ";
965 Out <<
"thread_local ";
970 Out <<
"__module_private__ ";
972 if (
D->isConstexpr()) {
974 T.removeLocalConst();
980 ?
D->getIdentifier()->deuglifiedName()
983 prettyPrintAttributes(
D, AttrPosAsWritten::Right);
987 bool ImplicitInit =
false;
988 if (
D->isCXXForRangeDecl()) {
992 dyn_cast<CXXConstructExpr>(
Init->IgnoreImplicit())) {
994 !Construct->isListInitialization()) {
995 ImplicitInit = Construct->getNumArgs() == 0 ||
996 Construct->getArg(0)->isDefaultArgument();
1006 SubPolicy.SuppressSpecifiers =
false;
1007 Init->printPretty(Out,
nullptr, SubPolicy, Indentation,
"\n", &Context);
1020 D->getAsmStringExpr()->printPretty(Out,
nullptr, Policy, Indentation,
"\n",
1026 assert(
D->getStmt());
1027 D->getStmt()->printPretty(Out,
nullptr, Policy, Indentation,
"\n", &Context);
1031 Out <<
"@import " <<
D->getImportedModule()->getFullModuleName()
1036 Out <<
"static_assert(";
1037 D->getAssertExpr()->printPretty(Out,
nullptr, Policy, Indentation,
"\n",
1039 if (
Expr *
E =
D->getMessage()) {
1041 E->
printPretty(Out,
nullptr, Policy, Indentation,
"\n", &Context);
1053 Out <<
"namespace ";
1054 if (
D->getDeclName())
1055 Out <<
D->getDeclName() <<
' ';
1058 VisitDeclContext(
D);
1063 Out <<
"using namespace ";
1064 D->getQualifier().
print(Out, Policy);
1065 Out << *
D->getNominatedNamespaceAsWritten();
1069 Out <<
"namespace " << *
D <<
" = ";
1070 D->getQualifier().
print(Out, Policy);
1071 Out << *
D->getAliasedNamespace();
1074void DeclPrinter::VisitEmptyDecl(
EmptyDecl *
D) {
1075 prettyPrintAttributes(
D);
1081 Out <<
"__module_private__ ";
1083 Out <<
D->getKindName() <<
' ';
1087 if (prettyPrintAttributes(
D, AttrPosAsWritten::Left))
1090 if (
D->getIdentifier()) {
1091 D->getQualifier().
print(Out, Policy);
1094 if (
auto *S = dyn_cast<ClassTemplateSpecializationDecl>(
D)) {
1096 S->getSpecializedTemplate()->getTemplateParameters();
1098 S->getTemplateArgsAsWritten();
1100 printTemplateArguments(TArgAsWritten->
arguments(), TParams);
1102 printTemplateArguments(S->getTemplateArgs().asArray(), TParams);
1106 prettyPrintAttributes(
D, AttrPosAsWritten::Right);
1108 if (
D->isCompleteDefinition()) {
1111 if (
D->getNumBases()) {
1114 BaseEnd =
D->bases_end();
Base != BaseEnd; ++
Base) {
1115 if (
Base !=
D->bases_begin())
1118 if (
Base->isVirtual())
1126 Out <<
Base->getType().getAsString(Policy);
1128 if (
Base->isPackExpansion())
1140 VisitDeclContext(
D);
1152 "unknown language in linkage specification");
1156 Out <<
"extern \"" << l <<
"\" ";
1157 if (
D->hasBraces()) {
1159 VisitDeclContext(
D);
1162 Visit(*
D->decls_begin());
1166 bool OmitTemplateKW) {
1173 if (!OmitTemplateKW)
1177 bool NeedComma =
false;
1178 for (
const Decl *Param : *Params) {
1179 if (Param->isImplicit())
1187 if (
const auto *TTP = dyn_cast<TemplateTypeParmDecl>(Param)) {
1188 VisitTemplateTypeParmDecl(TTP);
1189 }
else if (
auto NTTP = dyn_cast<NonTypeTemplateParmDecl>(Param)) {
1190 VisitNonTypeTemplateParmDecl(NTTP);
1191 }
else if (
auto TTPD = dyn_cast<TemplateTemplateParmDecl>(Param)) {
1192 VisitTemplateDecl(TTPD);
1199 if (
const Expr *RequiresClause = Params->getRequiresClause()) {
1200 Out <<
" requires ";
1201 RequiresClause->printPretty(Out,
nullptr, Policy, Indentation,
"\n",
1205 if (!OmitTemplateKW)
1212 for (
size_t I = 0,
E = Args.size(); I <
E; ++I) {
1216 Args[I].print(Policy, Out,
true);
1218 Args[I].print(Policy, Out,
1220 Policy, Params, I));
1228 for (
size_t I = 0,
E = Args.size(); I <
E; ++I) {
1232 Args[I].getArgument().print(Policy, Out,
true);
1234 Args[I].getArgument().print(
1243 printTemplateParameters(
D->getTemplateParameters());
1246 dyn_cast<TemplateTemplateParmDecl>(
D)) {
1247 if (TTP->wasDeclaredWithTypename())
1252 if (TTP->isParameterPack())
1254 else if (TTP->getDeclName())
1257 if (TTP->getDeclName()) {
1259 Out << TTP->getIdentifier()->deuglifiedName();
1261 Out << TTP->getDeclName();
1263 }
else if (
auto *TD =
D->getTemplatedDecl())
1265 else if (
const auto *
Concept = dyn_cast<ConceptDecl>(
D)) {
1266 Out <<
"concept " <<
Concept->getName() <<
" = " ;
1267 Concept->getConstraintExpr()->printPretty(Out,
nullptr, Policy, Indentation,
1273 prettyPrintPragmas(
D->getTemplatedDecl());
1277 I < NumTemplateParams; ++I)
1280 VisitRedeclarableTemplateDecl(
D);
1283 if (
D->getTemplatedDecl()->
hasAttr<OMPDeclareTargetDeclAttr>())
1284 Out <<
"#pragma omp end declare target\n";
1288 if (PrintInstantiation &&
1289 !isa<CXXDeductionGuideDecl>(
D->getTemplatedDecl())) {
1292 if (PrevDecl->
isDefined(Def) && Def != PrevDecl)
1294 for (
auto *I :
D->specializations())
1299 prettyPrintPragmas(I);
1306 VisitRedeclarableTemplateDecl(
D);
1308 if (PrintInstantiation) {
1309 for (
auto *I :
D->specializations())
1311 if (
D->isThisDeclarationADefinition())
1320void DeclPrinter::VisitClassTemplateSpecializationDecl(
1322 Out <<
"template<> ";
1323 VisitCXXRecordDecl(
D);
1326void DeclPrinter::VisitClassTemplatePartialSpecializationDecl(
1328 printTemplateParameters(
D->getTemplateParameters());
1329 VisitCXXRecordDecl(
D);
1336void DeclPrinter::PrintObjCMethodType(
ASTContext &Ctx,
1363 unsigned First =
true;
1364 for (
auto *Param : *Params) {
1371 switch (Param->getVariance()) {
1376 Out <<
"__covariant ";
1380 Out <<
"__contravariant ";
1384 Out << Param->getDeclName();
1386 if (Param->hasExplicitBound()) {
1387 Out <<
" : " << Param->getUnderlyingType().getAsString(Policy);
1404 std::string::size_type pos, lastPos = 0;
1407 pos =
name.find_first_of(
':', lastPos);
1410 Out <<
name.substr(lastPos, pos - lastPos) <<
':';
1412 PI->getObjCDeclQualifier(),
1424 prettyPrintAttributes(OMD);
1439 bool eolnOut =
false;
1441 Out <<
"@implementation " << I <<
" : " << *SID;
1443 Out <<
"@implementation " << I;
1449 for (
const auto *I : OID->
ivars()) {
1450 Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
1455 }
else if (SID || !OID->
decls().empty()) {
1459 VisitDeclContext(OID,
false);
1470 Out <<
"@class " << I;
1473 PrintObjCTypeParams(TypeParams);
1479 bool eolnOut =
false;
1481 prettyPrintAttributes(OID);
1485 Out <<
"@interface " << I;
1488 PrintObjCTypeParams(TypeParams);
1496 if (!Protocols.
empty()) {
1498 E = Protocols.
end(); I !=
E; ++I)
1499 Out << (I == Protocols.
begin() ?
'<' :
',') << **I;
1507 for (
const auto *I : OID->
ivars()) {
1508 Indent() << I->getASTContext()
1509 .getUnqualifiedObjCPointerType(I->getType())
1510 .getAsString(Policy) <<
' ' << *I <<
";\n";
1514 }
else if (SID || !OID->
decls().empty()) {
1519 VisitDeclContext(OID,
false);
1528 Out <<
"@protocol " << *PID <<
";\n";
1533 if (!Protocols.
empty()) {
1534 Out <<
"@protocol " << *PID;
1536 E = Protocols.
end(); I !=
E; ++I)
1537 Out << (I == Protocols.
begin() ?
'<' :
',') << **I;
1540 Out <<
"@protocol " << *PID <<
'\n';
1541 VisitDeclContext(PID,
false);
1546 Out <<
"@implementation ";
1550 Out <<
"<<error-type>>";
1551 Out <<
'(' << *PID <<
")\n";
1553 VisitDeclContext(PID,
false);
1559 Out <<
"@interface ";
1563 Out <<
"<<error-type>>";
1565 PrintObjCTypeParams(TypeParams);
1567 Out <<
"(" << *PID <<
")\n";
1568 if (PID->ivar_size() > 0) {
1571 for (
const auto *I : PID->ivars())
1572 Indent() << I->getASTContext().getUnqualifiedObjCPointerType(I->getType()).
1578 VisitDeclContext(PID,
false);
1585 Out <<
"@compatibility_alias " << *AID
1600 Out <<
"@required\n";
1602 Out <<
"@optional\n";
1611 Out << (first ?
"" :
", ") <<
"class";
1616 Out << (first ?
"" :
", ") <<
"direct";
1622 Out << (first ?
"" :
", ") <<
"nonatomic";
1626 Out << (first ?
"" :
", ") <<
"atomic";
1631 Out << (first ?
"" :
", ") <<
"assign";
1635 Out << (first ?
"" :
", ") <<
"retain";
1640 Out << (first ?
"" :
", ") <<
"strong";
1644 Out << (first ?
"" :
", ") <<
"copy";
1648 Out << (first ?
"" :
", ") <<
"weak";
1653 Out << (first ?
"" :
", ") <<
"unsafe_unretained";
1659 Out << (first ?
"" :
", ") <<
"readwrite";
1663 Out << (first ?
"" :
", ") <<
"readonly";
1668 Out << (first ?
"" :
", ") <<
"getter = ";
1673 Out << (first ?
"" :
", ") <<
"setter = ";
1684 Out << (first ?
"" :
", ") <<
"null_resettable";
1686 Out << (first ?
"" :
", ")
1698 Out <<
' ' << TypeStr;
1699 if (!StringRef(TypeStr).ends_with(
"*"))
1708 Out <<
"@synthesize ";
1716void DeclPrinter::VisitUsingDecl(
UsingDecl *
D) {
1717 if (!
D->isAccessDeclaration())
1719 if (
D->hasTypename())
1721 D->getQualifier().
print(Out, Policy);
1725 for (
const auto *Shadow :
D->shadows()) {
1726 if (
const auto *ConstructorShadow =
1727 dyn_cast<ConstructorUsingShadowDecl>(Shadow)) {
1728 assert(Shadow->getDeclContext() == ConstructorShadow->getDeclContext());
1729 Out << *ConstructorShadow->getNominatedBaseClass();
1737 Out <<
"using enum " <<
D->getEnumDecl();
1742 Out <<
"using typename ";
1743 D->getQualifier().
print(Out, Policy);
1744 Out <<
D->getDeclName();
1748 if (!
D->isAccessDeclaration())
1750 D->getQualifier().
print(Out, Policy);
1751 Out <<
D->getDeclName();
1759 Out <<
"#pragma omp threadprivate";
1760 if (!
D->varlist_empty()) {
1762 E =
D->varlist_end();
1764 Out << (I ==
D->varlist_begin() ?
'(' :
',');
1765 NamedDecl *ND = cast<DeclRefExpr>(*I)->getDecl();
1780 prettyPrintAttributes(
D);
1783 VisitDeclContext(
D);
1788 Out <<
"#pragma omp allocate";
1789 if (!
D->varlist_empty()) {
1791 E =
D->varlist_end();
1793 Out << (I ==
D->varlist_begin() ?
'(' :
',');
1794 NamedDecl *ND = cast<DeclRefExpr>(*I)->getDecl();
1799 if (!
D->clauselist_empty()) {
1809 Out <<
"#pragma omp requires ";
1810 if (!
D->clauselist_empty()) {
1812 for (
auto I =
D->clauselist_begin(),
E =
D->clauselist_end(); I !=
E; ++I)
1819 Out <<
"#pragma omp declare reduction (";
1821 const char *OpName =
1823 assert(OpName &&
"not an overloaded operator");
1826 assert(
D->getDeclName().isIdentifier());
1827 D->printName(Out, Policy);
1830 D->getType().
print(Out, Policy);
1832 D->getCombiner()->printPretty(Out,
nullptr, Policy, 0,
"\n", &Context);
1834 if (
auto *
Init =
D->getInitializer()) {
1835 Out <<
" initializer(";
1836 switch (
D->getInitializerKind()) {
1841 Out <<
"omp_priv = ";
1846 Init->printPretty(Out,
nullptr, Policy, 0,
"\n", &Context);
1856 Out <<
"#pragma omp declare mapper (";
1857 D->printName(Out, Policy);
1859 D->getType().
print(Out, Policy);
1861 Out <<
D->getVarName();
1863 if (!
D->clauselist_empty()) {
1865 for (
auto *
C :
D->clauselists()) {
1874 D->getInit()->printPretty(Out,
nullptr, Policy, Indentation,
"\n", &Context);
1879 TC->
print(Out, Policy);
1904void DeclPrinter::VisitNonTypeTemplateParmDecl(
1921 Out <<
"#pragma acc declare";
1922 if (!
D->clauses().empty()) {
1925 Printer.VisitClauseList(
D->clauses());
1931 Out <<
"#pragma acc routine";
1937 if (
D->getFunctionReference())
1938 D->getFunctionReference()->printPretty(Out,
nullptr, Policy, Indentation,
1945 if (!
D->clauses().empty()) {
1948 Printer.VisitClauseList(
D->clauses());
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 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.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
const LangOptions & getLangOpts() const
const clang::PrintingPolicy & getPrintingPolicy() const
QualType getUnqualifiedObjCPointerType(QualType type) const
getUnqualifiedObjCPointerType - Returns version of Objective-C pointer type with lifetime qualifier r...
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Attr - This represents one attribute.
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.
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
Represents a base class of a C++ class.
Represents a call to a C++ constructor.
Represents a C++ constructor within a class.
Represents a C++ conversion function within a class.
Represents a C++ deduction guide declaration.
TemplateDecl * getDeducedTemplate() const
Get the template for which this guide performs deduction.
Represents a C++ struct/union/class.
bool isLambda() const
Determine whether this class describes a lambda function object.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
Declaration of a class template.
Represents a class template specialization, which refers to a class template with a given set of temp...
decl_iterator - Iterates through the declarations stored within this context.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isTranslationUnit() const
void dumpDeclContext() const
decl_iterator decls_end() const
decl_range decls() const
decls_begin/decls_end - Iterate over the declarations stored in this context.
decl_iterator decls_begin() const
A simple visitor class that helps create declaration visitors.
Decl - This represents one declaration (or definition), e.g.
bool isModulePrivate() const
Whether this declaration was marked as being private to the module in which it was defined.
ASTContext & getASTContext() const LLVM_READONLY
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
virtual Stmt * getBody() const
getBody - If this Decl represents a declaration for a body of code, such as a function or method defi...
ObjCDeclQualifier
ObjCDeclQualifier - 'Qualifiers' written next to the return and parameter types in method declaration...
@ OBJC_TQ_CSNullability
The nullability qualifier is set when the nullability of the result or parameter was expressed via a ...
bool isInvalidDecl() const
SourceLocation getLocation() const
static void printGroup(Decl **Begin, unsigned NumDecls, raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation=0)
AccessSpecifier getAccess() const
void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const
std::string getAsString() const
Retrieve the human-readable string for this name.
TemplateParameterList * getTemplateParameterList(unsigned index) const
unsigned getNumTemplateParameterLists() const
Represents an empty-declaration.
An instance of this object exists for each enum constant that is defined.
Store information needed for an explicit specifier.
const Expr * getExpr() const
static ExplicitSpecifier getFromDecl(FunctionDecl *Function)
bool isSpecified() const
Determine if the declaration had an explicit specifier of any kind.
Represents an expression – generally a full-expression – that introduces cleanups to be run at the en...
This represents one expression.
Represents a member of a struct/union/class.
FriendDecl - Represents the declaration of a friend entity, which can be a function,...
Represents a function declaration or definition.
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
Represents a prototype with parameter type info, e.g.
ExceptionSpecificationType getExceptionSpecType() const
Get the kind of exception specification on this function.
bool hasTrailingReturn() const
Whether this function prototype has a trailing return type.
QualType getExceptionType(unsigned i) const
Return the ith exception type, where 0 <= i < getNumExceptions().
unsigned getNumExceptions() const
Return the number of types in the exception specification.
bool hasDynamicExceptionSpec() const
Return whether this function has a dynamic (throw) exception spec.
bool isVariadic() const
Whether this function prototype is variadic.
Expr * getNoexceptExpr() const
Return the expression inside noexcept(expression), or a null pointer if there is none (because the ex...
RefQualifierKind getRefQualifier() const
Retrieve the ref-qualifier associated with this function type.
Declaration of a template function.
FunctionType - C99 6.7.5.3 - Function Declarators.
HLSLBufferDecl - Represent a cbuffer or tbuffer declaration.
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...
Represents the declaration of a label.
Represents a linkage specification.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
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...
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...
Represents a C++ namespace alias.
Represent a C++ namespace.
NonTypeTemplateParmDecl - Declares a non-type template parameter, e.g., "Size" in.
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
bool isParameterPack() const
Whether this parameter is a non-type template parameter pack.
This represents '#pragma omp allocate ...' directive.
MutableArrayRef< Expr * >::iterator varlist_iterator
Pseudo declaration for capturing expressions.
This is a basic class for representing single OpenMP clause.
This represents '#pragma omp declare mapper ...' directive.
This represents '#pragma omp declare reduction ...' directive.
This represents '#pragma omp requires...' directive.
This represents '#pragma omp threadprivate ...' directive.
MutableArrayRef< Expr * >::iterator varlist_iterator
ObjCCategoryDecl - Represents a category declaration.
ObjCInterfaceDecl * getClassInterface()
ObjCTypeParamList * getTypeParamList() const
Retrieve the type parameter list associated with this category or extension.
ObjCCategoryImplDecl - An object of this class encapsulates a category @implementation declaration.
ObjCCompatibleAliasDecl - Represents alias of a class.
const ObjCInterfaceDecl * getClassInterface() const
const ObjCInterfaceDecl * getClassInterface() const
ObjCImplementationDecl - Represents a class definition - this is where method definitions are specifi...
std::string getNameAsString() const
Get the name of the class associated with this interface.
unsigned ivar_size() const
const ObjCInterfaceDecl * getSuperClass() const
Represents an ObjC class declaration.
unsigned ivar_size() const
ObjCTypeParamList * getTypeParamListAsWritten() const
Retrieve the type parameters written on this particular declaration of the class.
bool isThisDeclarationADefinition() const
Determine whether this particular declaration of this class is actually also a definition.
const ObjCProtocolList & getReferencedProtocols() const
const ObjCObjectType * getSuperClassType() const
Retrieve the superclass type.
ObjCInterfaceDecl * getSuperClass() const
ObjCList - This is a simple template class used to hold various lists of decls etc,...
ObjCMethodDecl - Represents an instance or class method declaration.
ObjCDeclQualifier getObjCDeclQualifier() const
ArrayRef< ParmVarDecl * > parameters() const
Stmt * getBody() const override
Retrieve the body of this method, if it has one.
Selector getSelector() const
bool isInstanceMethod() const
QualType getReturnType() const
Represents a pointer to an Objective C object.
Represents one property declaration in an Objective-C interface.
Selector getSetterName() const
Selector getGetterName() const
ObjCPropertyAttribute::Kind getPropertyAttributes() const
PropertyControl getPropertyImplementation() const
ObjCPropertyImplDecl - Represents implementation declaration of a property in a class or category imp...
ObjCIvarDecl * getPropertyIvarDecl() const
Kind getPropertyImplementation() const
ObjCPropertyDecl * getPropertyDecl() const
Represents an Objective-C protocol declaration.
bool isThisDeclarationADefinition() const
Determine whether this particular declaration is also the definition.
const ObjCProtocolList & getReferencedProtocols() const
Stores a list of Objective-C type parameters for a parameterized class or a category/extension thereo...
Represents a pack expansion of types.
Sugar for parentheses used when specifying types.
Represents a parameter to a function.
PointerType - C99 6.7.5.1 - Pointer Declarators.
A (possibly-)qualified type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
Represents a struct/union/class.
Base for LValueReferenceType and RValueReferenceType.
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.
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.
A template argument list.
const TemplateArgument & getArgument() const
void print(const PrintingPolicy &Policy, raw_ostream &Out, bool IncludeType) const
Print this template argument to the given output stream.
The base class of all kinds of template declarations (e.g., class, function, etc.).
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
void print(raw_ostream &Out, const ASTContext &Context, bool OmitTemplateKW=false) const
static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)
TemplateTemplateParmDecl - Declares a template template parameter, e.g., "T" in.
Declaration of a template type parameter.
bool wasDeclaredWithTypename() const
Whether this template type parameter was declared with the 'typename' keyword.
const TemplateArgumentLoc & getDefaultArgument() const
Retrieve the default argument, if any.
const TypeConstraint * getTypeConstraint() const
Returns the type constraint associated with this template parameter (if any).
bool hasDefaultArgument() const
Determine whether this template parameter has a default argument.
bool isParameterPack() const
Returns whether this is a parameter pack.
A declaration that models statements at global scope.
The top declaration context.
Represents the declaration of a typedef-name via a C++11 alias-declaration.
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
A container of type source information.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isSpecifierType() const
Returns true if this type can be represented by some set of type specifiers.
const T * getAs() const
Member-template getAs<specific type>'.
Represents the declaration of a typedef-name via the 'typedef' type specifier.
Base class for declarations which introduce a typedef-name.
Represents a dependent using declaration which was marked with typename.
Represents a dependent using declaration which was not marked with typename.
Represents a C++ using-declaration.
Represents C++ using-directive.
Represents a C++ using-enum-declaration.
Represents a shadow declaration implicitly introduced into a scope by a (resolved) using-declaration ...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
Represents a variable declaration or definition.
static const char * getStorageClassSpecifierString(StorageClass SC)
Return the string used to specify the storage class SC.
@ CInit
C-style initialization with assignment.
@ CallInit
Call-style initialization (C++98)
Represents a GCC generic vector type.
@ kind_nullability
Indicates that the nullability of the type was spelled with a property attribute rather than a type q...
The JSON file list parser is used to communicate input to InstallAPI.
llvm::StringRef getAccessSpelling(AccessSpecifier AS)
@ Unspecified
Whether values of this type can be null is (explicitly) unspecified.
@ ICIS_ListInit
Direct list-initialization.
@ RQ_None
No ref-qualifier was provided.
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
AccessSpecifier
A C++ access specifier (public, private, protected), plus the special value "none" which means differ...
StorageClass
Storage classes.
@ TSCS_thread_local
C++11 thread_local.
@ TSCS__Thread_local
C11 _Thread_local.
@ TSCS___thread
GNU __thread.
llvm::StringRef getNullabilitySpelling(NullabilityKind kind, bool isContextSensitive=false)
Retrieve the spelling of the given nullability kind.
bool isComputedNoexcept(ExceptionSpecificationType ESpecType)
bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)
@ Concept
The name was classified as a concept name.
const FunctionProtoType * T
llvm::StringRef getAsString(SyncScope S)
@ TSK_ImplicitInstantiation
This template specialization was implicitly instantiated from a template.
@ Invariant
The parameter is invariant: must match exactly.
@ Contravariant
The parameter is contravariant, e.g., X<T> is a subtype of X when the type parameter is covariant and...
@ Covariant
The parameter is covariant, e.g., X<T> is a subtype of X when the type parameter is covariant and T i...
const char * getOperatorSpelling(OverloadedOperatorKind Operator)
Retrieve the spelling of the given overloaded operator, without the preceding "operator" keyword.
@ EST_MSAny
Microsoft throw(...) extension.
Represents an explicit template argument list in C++, e.g., the "<int>" in "sort<int>".
ArrayRef< TemplateArgumentLoc > arguments() const
Describes how types, statements, expressions, and declarations should be printed.
unsigned FullyQualifiedName
When true, print the fully qualified name of function declarations.
unsigned PolishForDeclaration
When true, do certain refinement needed for producing proper declaration tag; such as,...
unsigned CleanUglifiedParameters
Whether to strip underscores when printing reserved parameter names.
unsigned SuppressSpecifiers
Whether we should suppress printing of the actual specifiers for the given type or declaration.
unsigned SuppressScope
Suppresses printing of scope specifiers.
unsigned Indentation
The number of spaces to use to indent each line.
unsigned SuppressInitializers
Suppress printing of variable initializers.
unsigned TerseOutput
Provide a 'terse' output.
unsigned PrintAsCanonical
Whether to print entities as written or canonically.