clang: lib/AST/TypePrinter.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

35#include "llvm/ADT/ArrayRef.h"

36#include "llvm/ADT/DenseMap.h"

37#include "llvm/ADT/SmallString.h"

38#include "llvm/ADT/StringRef.h"

39#include "llvm/ADT/Twine.h"

40#include "llvm/Support/Compiler.h"

41#include "llvm/Support/ErrorHandling.h"

42#include "llvm/Support/SaveAndRestore.h"

43#include "llvm/Support/raw_ostream.h"

44#include

45#include

46

47using namespace clang;

48

49namespace {

50

51

52

53class IncludeStrongLifetimeRAII {

54 PrintingPolicy &Policy;

55 bool Old;

56

57public:

58 explicit IncludeStrongLifetimeRAII(PrintingPolicy &Policy)

59 : Policy(Policy), Old(Policy.SuppressStrongLifetime) {

60 if (!Policy.SuppressLifetimeQualifiers)

61 Policy.SuppressStrongLifetime = false;

62 }

63

64 ~IncludeStrongLifetimeRAII() { Policy.SuppressStrongLifetime = Old; }

65};

66

67class ParamPolicyRAII {

68 PrintingPolicy &Policy;

69 bool Old;

70

71public:

72 explicit ParamPolicyRAII(PrintingPolicy &Policy)

73 : Policy(Policy), Old(Policy.SuppressSpecifiers) {

74 Policy.SuppressSpecifiers = false;

75 }

76

77 ~ParamPolicyRAII() { Policy.SuppressSpecifiers = Old; }

78};

79

80class DefaultTemplateArgsPolicyRAII {

81 PrintingPolicy &Policy;

82 bool Old;

83

84public:

85 explicit DefaultTemplateArgsPolicyRAII(PrintingPolicy &Policy)

86 : Policy(Policy), Old(Policy.SuppressDefaultTemplateArgs) {

87 Policy.SuppressDefaultTemplateArgs = false;

88 }

89

90 ~DefaultTemplateArgsPolicyRAII() { Policy.SuppressDefaultTemplateArgs = Old; }

91};

92

93class ElaboratedTypePolicyRAII {

94 PrintingPolicy &Policy;

95 bool SuppressTagKeyword;

96 bool SuppressScope;

97

98public:

99 explicit ElaboratedTypePolicyRAII(PrintingPolicy &Policy) : Policy(Policy) {

100 SuppressTagKeyword = Policy.SuppressTagKeyword;

101 SuppressScope = Policy.SuppressScope;

102 Policy.SuppressTagKeyword = true;

103 Policy.SuppressScope = true;

104 }

105

106 ~ElaboratedTypePolicyRAII() {

107 Policy.SuppressTagKeyword = SuppressTagKeyword;

108 Policy.SuppressScope = SuppressScope;

109 }

110};

111

112class TypePrinter {

113 PrintingPolicy Policy;

114 unsigned Indentation;

115 bool HasEmptyPlaceHolder = false;

116 bool InsideCCAttribute = false;

117

118public:

119 explicit TypePrinter(const PrintingPolicy &Policy, unsigned Indentation = 0)

120 : Policy(Policy), Indentation(Indentation) {}

121

122 void print(const Type *ty, Qualifiers qs, raw_ostream &OS,

123 StringRef PlaceHolder);

124 void print(QualType T, raw_ostream &OS, StringRef PlaceHolder);

125

126 static bool canPrefixQualifiers(const Type *T, bool &NeedARCStrongQualifier);

127 void spaceBeforePlaceHolder(raw_ostream &OS);

128 void printTypeSpec(NamedDecl *D, raw_ostream &OS);

129 void printTemplateId(const TemplateSpecializationType *T, raw_ostream &OS,

130 bool FullyQualify);

131

132 void printBefore(QualType T, raw_ostream &OS);

133 void printAfter(QualType T, raw_ostream &OS);

134 void printTagType(const TagType *T, raw_ostream &OS);

135 void printFunctionAfter(const FunctionType::ExtInfo &Info, raw_ostream &OS);

136#define ABSTRACT_TYPE(CLASS, PARENT)

137#define TYPE(CLASS, PARENT) \

138 void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \

139 void print##CLASS##After(const CLASS##Type *T, raw_ostream &OS);

140#include "clang/AST/TypeNodes.inc"

141

142private:

143 void printBefore(const Type *ty, Qualifiers qs, raw_ostream &OS);

144 void printAfter(const Type *ty, Qualifiers qs, raw_ostream &OS);

145};

146

147}

148

150 bool HasRestrictKeyword) {

151 bool appendSpace = false;

153 OS << "const";

154 appendSpace = true;

155 }

157 if (appendSpace) OS << ' ';

158 OS << "volatile";

159 appendSpace = true;

160 }

162 if (appendSpace) OS << ' ';

163 if (HasRestrictKeyword) {

164 OS << "restrict";

165 } else {

166 OS << "__restrict";

167 }

168 }

169}

170

171void TypePrinter::spaceBeforePlaceHolder(raw_ostream &OS) {

172 if (!HasEmptyPlaceHolder)

173 OS << ' ';

174}

175

180 return QT.split();

181}

182

183void TypePrinter::print(QualType t, raw_ostream &OS, StringRef PlaceHolder) {

185 print(split.Ty, split.Quals, OS, PlaceHolder);

186}

187

188void TypePrinter::print(const Type *T, Qualifiers Quals, raw_ostream &OS,

189 StringRef PlaceHolder) {

190 if (T) {

191 OS << "NULL TYPE";

192 return;

193 }

194

195 SaveAndRestore PHVal(HasEmptyPlaceHolder, PlaceHolder.empty());

196

197 printBefore(T, Quals, OS);

198 OS << PlaceHolder;

199 printAfter(T, Quals, OS);

200}

201

202bool TypePrinter::canPrefixQualifiers(const Type *T,

203 bool &NeedARCStrongQualifier) {

204

205

206

207

208

209 bool CanPrefixQualifiers = false;

210 NeedARCStrongQualifier = false;

211 const Type *UnderlyingType = T;

212 if (const auto *AT = dyn_cast(T))

213 UnderlyingType = AT->desugar().getTypePtr();

214 if (const auto *Subst = dyn_cast(T))

215 UnderlyingType = Subst->getReplacementType().getTypePtr();

216 Type::TypeClass TC = UnderlyingType->getTypeClass();

217

218 switch (TC) {

219 case Type::Auto:

220 case Type::Builtin:

221 case Type::Complex:

222 case Type::UnresolvedUsing:

223 case Type::Using:

224 case Type::Typedef:

225 case Type::TypeOfExpr:

226 case Type::TypeOf:

227 case Type::Decltype:

228 case Type::UnaryTransform:

229 case Type::Record:

230 case Type::Enum:

231 case Type::TemplateTypeParm:

232 case Type::SubstTemplateTypeParmPack:

233 case Type::SubstBuiltinTemplatePack:

234 case Type::DeducedTemplateSpecialization:

235 case Type::TemplateSpecialization:

236 case Type::InjectedClassName:

237 case Type::DependentName:

238 case Type::ObjCObject:

239 case Type::ObjCTypeParam:

240 case Type::ObjCInterface:

241 case Type::Atomic:

242 case Type::Pipe:

243 case Type::BitInt:

244 case Type::DependentBitInt:

245 case Type::BTFTagAttributed:

246 case Type::HLSLAttributedResource:

247 case Type::HLSLInlineSpirv:

248 case Type::PredefinedSugar:

249 CanPrefixQualifiers = true;

250 break;

251

252 case Type::ObjCObjectPointer:

255 break;

256

257 case Type::VariableArray:

258 case Type::DependentSizedArray:

259 NeedARCStrongQualifier = true;

260 [[fallthrough]];

261

262 case Type::ConstantArray:

263 case Type::IncompleteArray:

264 return canPrefixQualifiers(

265 cast(UnderlyingType)->getElementType().getTypePtr(),

266 NeedARCStrongQualifier);

267

268 case Type::Adjusted:

269 case Type::Decayed:

270 case Type::ArrayParameter:

271 case Type::Pointer:

272 case Type::BlockPointer:

273 case Type::LValueReference:

274 case Type::RValueReference:

275 case Type::MemberPointer:

276 case Type::DependentAddressSpace:

277 case Type::DependentVector:

278 case Type::DependentSizedExtVector:

279 case Type::Vector:

280 case Type::ExtVector:

281 case Type::ConstantMatrix:

282 case Type::DependentSizedMatrix:

283 case Type::FunctionProto:

284 case Type::FunctionNoProto:

285 case Type::Paren:

286 case Type::PackExpansion:

287 case Type::SubstTemplateTypeParm:

288 case Type::MacroQualified:

289 case Type::CountAttributed:

290 CanPrefixQualifiers = false;

291 break;

292

293 case Type::Attributed: {

294

295

297 CanPrefixQualifiers = AttrTy->getAttrKind() == attr::AddressSpace;

298 break;

299 }

300 case Type::PackIndexing: {

301 return canPrefixQualifiers(

303 NeedARCStrongQualifier);

304 }

305 }

306

307 return CanPrefixQualifiers;

308}

309

310void TypePrinter::printBefore(QualType T, raw_ostream &OS) {

312

313

314

315 Qualifiers Quals = Split.Quals;

316 if (const auto *Subst = dyn_cast(Split.Ty))

317 Quals -= QualType(Subst, 0).getQualifiers();

318

319 printBefore(Split.Ty, Quals, OS);

320}

321

322

323

324void TypePrinter::printBefore(const Type *T,Qualifiers Quals, raw_ostream &OS) {

326 return;

327

328 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder);

329

330

331

332 bool CanPrefixQualifiers = false;

333 bool NeedARCStrongQualifier = false;

334 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);

335

336 if (CanPrefixQualifiers && !Quals.empty()) {

337 if (NeedARCStrongQualifier) {

338 IncludeStrongLifetimeRAII Strong(Policy);

339 Quals.print(OS, Policy, true);

340 } else {

341 Quals.print(OS, Policy, true);

342 }

343 }

344

345 bool hasAfterQuals = false;

346 if (!CanPrefixQualifiers && !Quals.empty()) {

348 if (hasAfterQuals)

349 HasEmptyPlaceHolder = false;

350 }

351

353#define ABSTRACT_TYPE(CLASS, PARENT)

354#define TYPE(CLASS, PARENT) case Type::CLASS: \

355 print##CLASS##Before(cast<CLASS##Type>(T), OS); \

356 break;

357#include "clang/AST/TypeNodes.inc"

358 }

359

360 if (hasAfterQuals) {

361 if (NeedARCStrongQualifier) {

362 IncludeStrongLifetimeRAII Strong(Policy);

363 Quals.print(OS, Policy, !PrevPHIsEmpty.get());

364 } else {

365 Quals.print(OS, Policy, !PrevPHIsEmpty.get());

366 }

367 }

368}

369

370void TypePrinter::printAfter(QualType t, raw_ostream &OS) {

372 printAfter(split.Ty, split.Quals, OS);

373}

374

375

376

377void TypePrinter::printAfter(const Type *T, Qualifiers Quals, raw_ostream &OS) {

379#define ABSTRACT_TYPE(CLASS, PARENT)

380#define TYPE(CLASS, PARENT) case Type::CLASS: \

381 print##CLASS##After(cast<CLASS##Type>(T), OS); \

382 break;

383#include "clang/AST/TypeNodes.inc"

384 }

385}

386

387void TypePrinter::printBuiltinBefore(const BuiltinType *T, raw_ostream &OS) {

388 OS << T->getName(Policy);

389 spaceBeforePlaceHolder(OS);

390}

391

392void TypePrinter::printBuiltinAfter(const BuiltinType *T, raw_ostream &OS) {}

393

394void TypePrinter::printComplexBefore(const ComplexType *T, raw_ostream &OS) {

395 OS << "_Complex ";

396 printBefore(T->getElementType(), OS);

397}

398

399void TypePrinter::printComplexAfter(const ComplexType *T, raw_ostream &OS) {

400 printAfter(T->getElementType(), OS);

401}

402

403void TypePrinter::printPointerBefore(const PointerType *T, raw_ostream &OS) {

404 IncludeStrongLifetimeRAII Strong(Policy);

405 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

407

408

410 OS << '(';

411 OS << '*';

412}

413

414void TypePrinter::printPointerAfter(const PointerType *T, raw_ostream &OS) {

415 IncludeStrongLifetimeRAII Strong(Policy);

416 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

417

418

420 OS << ')';

422}

423

424void TypePrinter::printBlockPointerBefore(const BlockPointerType *T,

425 raw_ostream &OS) {

426 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

428 OS << '^';

429}

430

431void TypePrinter::printBlockPointerAfter(const BlockPointerType *T,

432 raw_ostream &OS) {

433 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

435}

436

437

438

444

445void TypePrinter::printLValueReferenceBefore(const LValueReferenceType *T,

446 raw_ostream &OS) {

447 IncludeStrongLifetimeRAII Strong(Policy);

448 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

450 printBefore(Inner, OS);

451

452

454 OS << '(';

455 OS << '&';

456}

457

458void TypePrinter::printLValueReferenceAfter(const LValueReferenceType *T,

459 raw_ostream &OS) {

460 IncludeStrongLifetimeRAII Strong(Policy);

461 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

463

464

466 OS << ')';

467 printAfter(Inner, OS);

468}

469

470void TypePrinter::printRValueReferenceBefore(const RValueReferenceType *T,

471 raw_ostream &OS) {

472 IncludeStrongLifetimeRAII Strong(Policy);

473 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

475 printBefore(Inner, OS);

476

477

479 OS << '(';

480 OS << "&&";

481}

482

483void TypePrinter::printRValueReferenceAfter(const RValueReferenceType *T,

484 raw_ostream &OS) {

485 IncludeStrongLifetimeRAII Strong(Policy);

486 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

488

489

491 OS << ')';

492 printAfter(Inner, OS);

493}

494

495void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,

496 raw_ostream &OS) {

497 IncludeStrongLifetimeRAII Strong(Policy);

498 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

500

501

503 OS << '(';

504 T->getQualifier().print(OS, Policy);

505 OS << "*";

506}

507

508void TypePrinter::printMemberPointerAfter(const MemberPointerType *T,

509 raw_ostream &OS) {

510 IncludeStrongLifetimeRAII Strong(Policy);

511 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

512

513

515 OS << ')';

517}

518

519void TypePrinter::printConstantArrayBefore(const ConstantArrayType *T,

520 raw_ostream &OS) {

521 IncludeStrongLifetimeRAII Strong(Policy);

522 printBefore(T->getElementType(), OS);

523}

524

525void TypePrinter::printConstantArrayAfter(const ConstantArrayType *T,

526 raw_ostream &OS) {

527 OS << '[';

528 if (T->getIndexTypeQualifiers().hasQualifiers()) {

531 OS << ' ';

532 }

533

534 if (T->getSizeModifier() == ArraySizeModifier::Static)

535 OS << "static ";

536

537 OS << T->getZExtSize() << ']';

538 printAfter(T->getElementType(), OS);

539}

540

541void TypePrinter::printIncompleteArrayBefore(const IncompleteArrayType *T,

542 raw_ostream &OS) {

543 IncludeStrongLifetimeRAII Strong(Policy);

544 printBefore(T->getElementType(), OS);

545}

546

547void TypePrinter::printIncompleteArrayAfter(const IncompleteArrayType *T,

548 raw_ostream &OS) {

549 OS << "[]";

550 printAfter(T->getElementType(), OS);

551}

552

553void TypePrinter::printVariableArrayBefore(const VariableArrayType *T,

554 raw_ostream &OS) {

555 IncludeStrongLifetimeRAII Strong(Policy);

556 printBefore(T->getElementType(), OS);

557}

558

559void TypePrinter::printVariableArrayAfter(const VariableArrayType *T,

560 raw_ostream &OS) {

561 OS << '[';

562 if (T->getIndexTypeQualifiers().hasQualifiers()) {

564 OS << ' ';

565 }

566

567 if (T->getSizeModifier() == ArraySizeModifier::Static)

568 OS << "static ";

569 else if (T->getSizeModifier() == ArraySizeModifier::Star)

570 OS << '*';

571

572 if (T->getSizeExpr())

573 T->getSizeExpr()->printPretty(OS, nullptr, Policy);

574 OS << ']';

575

576 printAfter(T->getElementType(), OS);

577}

578

579void TypePrinter::printAdjustedBefore(const AdjustedType *T, raw_ostream &OS) {

580

581

582 printBefore(T->getAdjustedType(), OS);

583}

584

585void TypePrinter::printAdjustedAfter(const AdjustedType *T, raw_ostream &OS) {

586 printAfter(T->getAdjustedType(), OS);

587}

588

589void TypePrinter::printDecayedBefore(const DecayedType *T, raw_ostream &OS) {

590

591 printAdjustedBefore(T, OS);

592}

593

594void TypePrinter::printArrayParameterAfter(const ArrayParameterType *T,

595 raw_ostream &OS) {

596 printConstantArrayAfter(T, OS);

597}

598

599void TypePrinter::printArrayParameterBefore(const ArrayParameterType *T,

600 raw_ostream &OS) {

601 printConstantArrayBefore(T, OS);

602}

603

604void TypePrinter::printDecayedAfter(const DecayedType *T, raw_ostream &OS) {

605 printAdjustedAfter(T, OS);

606}

607

608void TypePrinter::printDependentSizedArrayBefore(

609 const DependentSizedArrayType *T,

610 raw_ostream &OS) {

611 IncludeStrongLifetimeRAII Strong(Policy);

612 printBefore(T->getElementType(), OS);

613}

614

615void TypePrinter::printDependentSizedArrayAfter(

616 const DependentSizedArrayType *T,

617 raw_ostream &OS) {

618 OS << '[';

619 if (T->getSizeExpr())

620 T->getSizeExpr()->printPretty(OS, nullptr, Policy);

621 OS << ']';

622 printAfter(T->getElementType(), OS);

623}

624

625void TypePrinter::printDependentAddressSpaceBefore(

626 const DependentAddressSpaceType *T, raw_ostream &OS) {

628}

629

630void TypePrinter::printDependentAddressSpaceAfter(

631 const DependentAddressSpaceType *T, raw_ostream &OS) {

632 OS << " __attribute__((address_space(";

633 if (T->getAddrSpaceExpr())

634 T->getAddrSpaceExpr()->printPretty(OS, nullptr, Policy);

635 OS << ")))";

637}

638

639void TypePrinter::printDependentSizedExtVectorBefore(

640 const DependentSizedExtVectorType *T,

641 raw_ostream &OS) {

643 OS << "vector<";

644 printBefore(T->getElementType(), OS);

645}

646

647void TypePrinter::printDependentSizedExtVectorAfter(

648 const DependentSizedExtVectorType *T,

649 raw_ostream &OS) {

651 OS << ", ";

652 if (T->getSizeExpr())

653 T->getSizeExpr()->printPretty(OS, nullptr, Policy);

654 OS << ">";

655 } else {

656 OS << " __attribute__((ext_vector_type(";

657 if (T->getSizeExpr())

658 T->getSizeExpr()->printPretty(OS, nullptr, Policy);

659 OS << ")))";

660 }

661 printAfter(T->getElementType(), OS);

662}

663

664void TypePrinter::printVectorBefore(const VectorType *T, raw_ostream &OS) {

665 switch (T->getVectorKind()) {

666 case VectorKind::AltiVecPixel:

667 OS << "__vector __pixel ";

668 break;

669 case VectorKind::AltiVecBool:

670 OS << "__vector __bool ";

671 printBefore(T->getElementType(), OS);

672 break;

673 case VectorKind::AltiVecVector:

674 OS << "__vector ";

675 printBefore(T->getElementType(), OS);

676 break;

677 case VectorKind::Neon:

678 OS << "__attribute__((neon_vector_type("

679 << T->getNumElements() << "))) ";

680 printBefore(T->getElementType(), OS);

681 break;

682 case VectorKind::NeonPoly:

683 OS << "__attribute__((neon_polyvector_type(" <<

684 T->getNumElements() << "))) ";

685 printBefore(T->getElementType(), OS);

686 break;

687 case VectorKind::Generic: {

688

689

690 OS << "__attribute__((__vector_size__("

691 << T->getNumElements()

692 << " * sizeof(";

693 print(T->getElementType(), OS, StringRef());

694 OS << ")))) ";

695 printBefore(T->getElementType(), OS);

696 break;

697 }

698 case VectorKind::SveFixedLengthData:

699 case VectorKind::SveFixedLengthPredicate:

700

701

702 OS << "__attribute__((__arm_sve_vector_bits__(";

703

704 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)

705

706

707 OS << T->getNumElements() * 8;

708 else

709 OS << T->getNumElements();

710

711 OS << " * sizeof(";

712 print(T->getElementType(), OS, StringRef());

713

714 OS << ") * 8))) ";

715 printBefore(T->getElementType(), OS);

716 break;

717 case VectorKind::RVVFixedLengthData:

718 case VectorKind::RVVFixedLengthMask:

719 case VectorKind::RVVFixedLengthMask_1:

720 case VectorKind::RVVFixedLengthMask_2:

721 case VectorKind::RVVFixedLengthMask_4:

722

723

724 OS << "__attribute__((__riscv_rvv_vector_bits__(";

725

726 OS << T->getNumElements();

727

728 OS << " * sizeof(";

729 print(T->getElementType(), OS, StringRef());

730

731 OS << ") * 8))) ";

732 printBefore(T->getElementType(), OS);

733 break;

734 }

735}

736

737void TypePrinter::printVectorAfter(const VectorType *T, raw_ostream &OS) {

738 printAfter(T->getElementType(), OS);

739}

740

741void TypePrinter::printDependentVectorBefore(

742 const DependentVectorType *T, raw_ostream &OS) {

743 switch (T->getVectorKind()) {

744 case VectorKind::AltiVecPixel:

745 OS << "__vector __pixel ";

746 break;

747 case VectorKind::AltiVecBool:

748 OS << "__vector __bool ";

749 printBefore(T->getElementType(), OS);

750 break;

751 case VectorKind::AltiVecVector:

752 OS << "__vector ";

753 printBefore(T->getElementType(), OS);

754 break;

755 case VectorKind::Neon:

756 OS << "__attribute__((neon_vector_type(";

757 if (T->getSizeExpr())

758 T->getSizeExpr()->printPretty(OS, nullptr, Policy);

759 OS << "))) ";

760 printBefore(T->getElementType(), OS);

761 break;

762 case VectorKind::NeonPoly:

763 OS << "__attribute__((neon_polyvector_type(";

764 if (T->getSizeExpr())

765 T->getSizeExpr()->printPretty(OS, nullptr, Policy);

766 OS << "))) ";

767 printBefore(T->getElementType(), OS);

768 break;

769 case VectorKind::Generic: {

770

771

772 OS << "__attribute__((__vector_size__(";

773 if (T->getSizeExpr())

774 T->getSizeExpr()->printPretty(OS, nullptr, Policy);

775 OS << " * sizeof(";

776 print(T->getElementType(), OS, StringRef());

777 OS << ")))) ";

778 printBefore(T->getElementType(), OS);

779 break;

780 }

781 case VectorKind::SveFixedLengthData:

782 case VectorKind::SveFixedLengthPredicate:

783

784

785 OS << "__attribute__((__arm_sve_vector_bits__(";

786 if (T->getSizeExpr()) {

787 T->getSizeExpr()->printPretty(OS, nullptr, Policy);

788 if (T->getVectorKind() == VectorKind::SveFixedLengthPredicate)

789

790

791 OS << " * 8";

792 OS << " * sizeof(";

793 print(T->getElementType(), OS, StringRef());

794

795 OS << ") * 8";

796 }

797 OS << "))) ";

798 printBefore(T->getElementType(), OS);

799 break;

800 case VectorKind::RVVFixedLengthData:

801 case VectorKind::RVVFixedLengthMask:

802 case VectorKind::RVVFixedLengthMask_1:

803 case VectorKind::RVVFixedLengthMask_2:

804 case VectorKind::RVVFixedLengthMask_4:

805

806

807 OS << "__attribute__((__riscv_rvv_vector_bits__(";

808 if (T->getSizeExpr()) {

809 T->getSizeExpr()->printPretty(OS, nullptr, Policy);

810 OS << " * sizeof(";

811 print(T->getElementType(), OS, StringRef());

812

813 OS << ") * 8";

814 }

815 OS << "))) ";

816 printBefore(T->getElementType(), OS);

817 break;

818 }

819}

820

821void TypePrinter::printDependentVectorAfter(

822 const DependentVectorType *T, raw_ostream &OS) {

823 printAfter(T->getElementType(), OS);

824}

825

826void TypePrinter::printExtVectorBefore(const ExtVectorType *T,

827 raw_ostream &OS) {

829 OS << "vector<";

830 printBefore(T->getElementType(), OS);

831}

832

833void TypePrinter::printExtVectorAfter(const ExtVectorType *T, raw_ostream &OS) {

834 printAfter(T->getElementType(), OS);

835

837 OS << ", ";

838 OS << T->getNumElements();

839 OS << ">";

840 } else {

841 OS << " __attribute__((ext_vector_type(";

842 OS << T->getNumElements();

843 OS << ")))";

844 }

845}

846

848 OS << T->getNumRows() << ", " << T->getNumColumns();

849}

850

852 raw_ostream &OS) {

853 OS << "matrix<";

854 TP.printBefore(T->getElementType(), OS);

855}

856

858 OS << ", ";

860 OS << ">";

861}

862

864 raw_ostream &OS) {

865 TP.printBefore(T->getElementType(), OS);

866 OS << " __attribute__((matrix_type(";

868 OS << ")))";

869}

870

871void TypePrinter::printConstantMatrixBefore(const ConstantMatrixType *T,

872 raw_ostream &OS) {

875 return;

876 }

878}

879

880void TypePrinter::printConstantMatrixAfter(const ConstantMatrixType *T,

881 raw_ostream &OS) {

884 return;

885 }

886 printAfter(T->getElementType(), OS);

887}

888

889void TypePrinter::printDependentSizedMatrixBefore(

890 const DependentSizedMatrixType *T, raw_ostream &OS) {

891 printBefore(T->getElementType(), OS);

892 OS << " __attribute__((matrix_type(";

893 if (T->getRowExpr()) {

894 T->getRowExpr()->printPretty(OS, nullptr, Policy);

895 }

896 OS << ", ";

897 if (T->getColumnExpr()) {

898 T->getColumnExpr()->printPretty(OS, nullptr, Policy);

899 }

900 OS << ")))";

901}

902

903void TypePrinter::printDependentSizedMatrixAfter(

904 const DependentSizedMatrixType *T, raw_ostream &OS) {

905 printAfter(T->getElementType(), OS);

906}

907

908void

911 const {

913 OS << " throw(";

915 OS << "...";

916 else

918 if (I)

919 OS << ", ";

920

922 }

923 OS << ')';

925 OS << " __attribute__((nothrow))";

927 OS << " noexcept";

928

929

931 OS << '(';

934 OS << ')';

935 }

936 }

937}

938

939void TypePrinter::printFunctionProtoBefore(const FunctionProtoType *T,

940 raw_ostream &OS) {

941 if (T->hasTrailingReturn()) {

942 OS << "auto ";

943 if (!HasEmptyPlaceHolder)

944 OS << '(';

945 } else {

946

947 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);

948 printBefore(T->getReturnType(), OS);

949 if (!PrevPHIsEmpty.get())

950 OS << '(';

951 }

952}

953

955 switch (ABI) {

957 llvm_unreachable("asking for spelling of ordinary parameter ABI");

959 return "swift_context";

961 return "swift_async_context";

963 return "swift_error_result";

965 return "swift_indirect_result";

967 return "out";

969 return "inout";

970 }

971 llvm_unreachable("bad parameter ABI kind");

972}

973

975 raw_ostream &OS) {

976

977 if (!HasEmptyPlaceHolder)

978 OS << ')';

979 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

980

981 OS << '(';

982 {

983 ParamPolicyRAII ParamPolicy(Policy);

984 for (unsigned i = 0, e = T->getNumParams(); i != e; ++i) {

985 if (i) OS << ", ";

986

987 auto EPI = T->getExtParameterInfo(i);

988 if (EPI.isConsumed()) OS << "__attribute__((ns_consumed)) ";

989 if (EPI.isNoEscape())

990 OS << "__attribute__((noescape)) ";

991 auto ABI = EPI.getABI();

995

996

997

998

999 print(T->getParamType(i).getNonReferenceType(), OS, StringRef());

1000 continue;

1001 }

1002 } else if (ABI != ParameterABI::Ordinary)

1004

1006 }

1007 }

1008

1011 OS << ", ";

1012 OS << "...";

1014

1015 OS << "void";

1016 }

1017

1018 OS << ')';

1019

1020 FunctionType::ExtInfo Info = T->getExtInfo();

1022

1024 OS << " __arm_streaming_compatible";

1026 OS << " __arm_streaming";

1028 OS << "__arm_agnostic(\"sme_za_state\")";

1030 OS << " __arm_preserves(\"za\")";

1032 OS << " __arm_in(\"za\")";

1034 OS << " __arm_out(\"za\")";

1036 OS << " __arm_inout(\"za\")";

1038 OS << " __arm_preserves(\"zt0\")";

1040 OS << " __arm_in(\"zt0\")";

1042 OS << " __arm_out(\"zt0\")";

1044 OS << " __arm_inout(\"zt0\")";

1045

1046 printFunctionAfter(Info, OS);

1047

1050

1053 break;

1054

1056 OS << " &";

1057 break;

1058

1060 OS << " &&";

1061 break;

1062 }

1064

1066 for (const auto &CFE : FX) {

1067 OS << " __attribute__((" << CFE.Effect.name();

1068 if (const Expr *E = CFE.Cond.getCondition()) {

1069 OS << '(';

1070 E->printPretty(OS, nullptr, Policy);

1071 OS << ')';

1072 }

1073 OS << "))";

1074 }

1075

1077 OS << " __attribute__((cfi_unchecked_callee))";

1078

1080 OS << " -> ";

1082 } else

1084}

1085

1086void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,

1087 raw_ostream &OS) {

1088 if (!InsideCCAttribute) {

1089 switch (Info.getCC()) {

1091

1092

1093

1094

1095

1096

1097

1098 break;

1100 OS << " __attribute__((stdcall))";

1101 break;

1103 OS << " __attribute__((fastcall))";

1104 break;

1106 OS << " __attribute__((thiscall))";

1107 break;

1109 OS << " __attribute__((vectorcall))";

1110 break;

1112 OS << " __attribute__((pascal))";

1113 break;

1115 OS << " __attribute__((pcs(\"aapcs\")))";

1116 break;

1118 OS << " __attribute__((pcs(\"aapcs-vfp\")))";

1119 break;

1121 OS << " __attribute__((aarch64_vector_pcs))";

1122 break;

1124 OS << " __attribute__((aarch64_sve_pcs))";

1125 break;

1127 OS << " __attribute__((device_kernel))";

1128 break;

1130 OS << " __attribute__((intel_ocl_bicc))";

1131 break;

1133 OS << " __attribute__((ms_abi))";

1134 break;

1136 OS << " __attribute__((sysv_abi))";

1137 break;

1139 OS << " __attribute__((regcall))";

1140 break;

1142

1143 break;

1145 OS << " __attribute__((swiftcall))";

1146 break;

1148 OS << "__attribute__((swiftasynccall))";

1149 break;

1151 OS << " __attribute__((preserve_most))";

1152 break;

1154 OS << " __attribute__((preserve_all))";

1155 break;

1157 OS << " __attribute__((m68k_rtd))";

1158 break;

1160 OS << " __attribute__((preserve_none))";

1161 break;

1163 OS << "__attribute__((riscv_vector_cc))";

1164 break;

1165#define CC_VLS_CASE(ABI_VLEN) \

1166 case CC_RISCVVLSCall_##ABI_VLEN: \

1167 OS << "__attribute__((riscv_vls_cc" #ABI_VLEN "))"; \

1168 break;

1181#undef CC_VLS_CASE

1182 }

1183 }

1184

1186 OS << " __attribute__((noreturn))";

1188 OS << " __attribute__((cmse_nonsecure_call))";

1190 OS << " __attribute__((ns_returns_retained))";

1192 OS << " __attribute__((regparm ("

1195 OS << " __attribute__((no_caller_saved_registers))";

1197 OS << " __attribute__((nocf_check))";

1198}

1199

1200void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,

1201 raw_ostream &OS) {

1202

1203 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);

1205 if (!PrevPHIsEmpty.get())

1206 OS << '(';

1207}

1208

1209void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,

1210 raw_ostream &OS) {

1211

1212 if (!HasEmptyPlaceHolder)

1213 OS << ')';

1214 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

1215

1216 OS << "()";

1217 printFunctionAfter(T->getExtInfo(), OS);

1219}

1220

1221void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {

1222

1223

1224

1225

1228

1231 spaceBeforePlaceHolder(OS);

1232}

1233

1234void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,

1235 raw_ostream &OS) {

1236 OS << TypeWithKeyword::getKeywordName(T->getKeyword());

1237 if (T->getKeyword() != ElaboratedTypeKeyword::None)

1238 OS << ' ';

1239 auto *D = T->getDecl();

1242 } else {

1243 T->getQualifier().print(OS, Policy);

1244 }

1246 spaceBeforePlaceHolder(OS);

1247}

1248

1249void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,

1250 raw_ostream &OS) {}

1251

1252void TypePrinter::printUsingBefore(const UsingType *T, raw_ostream &OS) {

1253 OS << TypeWithKeyword::getKeywordName(T->getKeyword());

1254 if (T->getKeyword() != ElaboratedTypeKeyword::None)

1255 OS << ' ';

1256 auto *D = T->getDecl();

1259 } else {

1260 T->getQualifier().print(OS, Policy);

1261 }

1263 spaceBeforePlaceHolder(OS);

1264}

1265

1266void TypePrinter::printUsingAfter(const UsingType *T, raw_ostream &OS) {}

1267

1268void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {

1269 OS << TypeWithKeyword::getKeywordName(T->getKeyword());

1270 if (T->getKeyword() != ElaboratedTypeKeyword::None)

1271 OS << ' ';

1272 auto *D = T->getDecl();

1275 } else {

1276 T->getQualifier().print(OS, Policy);

1277 }

1279 spaceBeforePlaceHolder(OS);

1280}

1281

1282void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType *T,

1283 raw_ostream &OS) {

1284 StringRef MacroName = T->getMacroIdentifier()->getName();

1285 OS << MacroName << " ";

1286

1287

1288

1289 printBefore(T->getModifiedType(), OS);

1290}

1291

1292void TypePrinter::printMacroQualifiedAfter(const MacroQualifiedType *T,

1293 raw_ostream &OS) {

1294 printAfter(T->getModifiedType(), OS);

1295}

1296

1297void TypePrinter::printTypedefAfter(const TypedefType *T, raw_ostream &OS) {}

1298

1299void TypePrinter::printTypeOfExprBefore(const TypeOfExprType *T,

1300 raw_ostream &OS) {

1301 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual "

1302 : "typeof ");

1303 if (T->getUnderlyingExpr())

1304 T->getUnderlyingExpr()->printPretty(OS, nullptr, Policy);

1305 spaceBeforePlaceHolder(OS);

1306}

1307

1308void TypePrinter::printTypeOfExprAfter(const TypeOfExprType *T,

1309 raw_ostream &OS) {}

1310

1311void TypePrinter::printTypeOfBefore(const TypeOfType *T, raw_ostream &OS) {

1312 OS << (T->getKind() == TypeOfKind::Unqualified ? "typeof_unqual("

1313 : "typeof(");

1314 print(T->getUnmodifiedType(), OS, StringRef());

1315 OS << ')';

1316 spaceBeforePlaceHolder(OS);

1317}

1318

1319void TypePrinter::printTypeOfAfter(const TypeOfType *T, raw_ostream &OS) {}

1320

1321void TypePrinter::printDecltypeBefore(const DecltypeType *T, raw_ostream &OS) {

1322 OS << "decltype(";

1323 if (const Expr *E = T->getUnderlyingExpr()) {

1324 PrintingPolicy ExprPolicy = Policy;

1326 E->printPretty(OS, nullptr, ExprPolicy);

1327 }

1328 OS << ')';

1329 spaceBeforePlaceHolder(OS);

1330}

1331

1332void TypePrinter::printPackIndexingBefore(const PackIndexingType *T,

1333 raw_ostream &OS) {

1334 if (T->hasSelectedType()) {

1335 OS << T->getSelectedType();

1336 } else {

1337 OS << T->getPattern() << "...[";

1338 T->getIndexExpr()->printPretty(OS, nullptr, Policy);

1339 OS << "]";

1340 }

1341 spaceBeforePlaceHolder(OS);

1342}

1343

1344void TypePrinter::printPackIndexingAfter(const PackIndexingType *T,

1345 raw_ostream &OS) {}

1346

1347void TypePrinter::printDecltypeAfter(const DecltypeType *T, raw_ostream &OS) {}

1348

1349void TypePrinter::printUnaryTransformBefore(const UnaryTransformType *T,

1350 raw_ostream &OS) {

1351 IncludeStrongLifetimeRAII Strong(Policy);

1352

1353 static llvm::DenseMap<int, const char *> Transformation = {{

1354#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \

1355 {UnaryTransformType::Enum, "__" #Trait},

1356#include "clang/Basic/TransformTypeTraits.def"

1357 }};

1358 OS << Transformation[T->getUTTKind()] << '(';

1359 print(T->getBaseType(), OS, StringRef());

1360 OS << ')';

1361 spaceBeforePlaceHolder(OS);

1362}

1363

1364void TypePrinter::printUnaryTransformAfter(const UnaryTransformType *T,

1365 raw_ostream &OS) {}

1366

1367void TypePrinter::printAutoBefore(const AutoType *T, raw_ostream &OS) {

1368

1369 if (T->getDeducedType().isNull()) {

1370 printBefore(T->getDeducedType(), OS);

1371 } else {

1372 if (T->isConstrained()) {

1373

1374

1375 T->getTypeConstraintConcept()->getDeclName().print(OS, Policy);

1376 auto Args = T->getTypeConstraintArguments();

1377 if (!Args.empty())

1378 printTemplateArgumentList(

1379 OS, Args, Policy,

1380 T->getTypeConstraintConcept()->getTemplateParameters());

1381 OS << ' ';

1382 }

1383 switch (T->getKeyword()) {

1384 case AutoTypeKeyword::Auto: OS << "auto"; break;

1385 case AutoTypeKeyword::DecltypeAuto: OS << "decltype(auto)"; break;

1386 case AutoTypeKeyword::GNUAutoType: OS << "__auto_type"; break;

1387 }

1388 spaceBeforePlaceHolder(OS);

1389 }

1390}

1391

1392void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {

1393

1394 if (T->getDeducedType().isNull())

1395 printAfter(T->getDeducedType(), OS);

1396}

1397

1398void TypePrinter::printDeducedTemplateSpecializationBefore(

1399 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {

1401 T->getKeyword() != ElaboratedTypeKeyword::None)

1403

1405

1406

1407

1408

1409

1410

1411 ArrayRef Args;

1412 TemplateDecl *DeducedTD = nullptr;

1413 if (T->getDeducedType().isNull()) {

1414 if (const auto *TST =

1415 dyn_cast(T->getDeducedType())) {

1416 DeducedTD = TST->getTemplateName().getAsTemplateDecl(

1417 true);

1418 Args = TST->template_arguments();

1419 } else {

1420

1423 DeducedTD = CD->getSpecializedTemplate();

1424 Args = CD->getTemplateArgs().asArray();

1425 }

1426

1427

1428

1429

1430

1431

1433 true)))

1435 }

1436

1437 {

1438 IncludeStrongLifetimeRAII Strong(Policy);

1439 Name.print(OS, Policy);

1440 }

1441 if (DeducedTD) {

1442 printTemplateArgumentList(OS, Args, Policy,

1444 }

1445

1446 spaceBeforePlaceHolder(OS);

1447}

1448

1449void TypePrinter::printDeducedTemplateSpecializationAfter(

1450 const DeducedTemplateSpecializationType *T, raw_ostream &OS) {

1451

1452 if (T->getDeducedType().isNull())

1453 printAfter(T->getDeducedType(), OS);

1454}

1455

1456void TypePrinter::printAtomicBefore(const AtomicType *T, raw_ostream &OS) {

1457 IncludeStrongLifetimeRAII Strong(Policy);

1458

1459 OS << "_Atomic(";

1460 print(T->getValueType(), OS, StringRef());

1461 OS << ')';

1462 spaceBeforePlaceHolder(OS);

1463}

1464

1465void TypePrinter::printAtomicAfter(const AtomicType *T, raw_ostream &OS) {}

1466

1467void TypePrinter::printPipeBefore(const PipeType *T, raw_ostream &OS) {

1468 IncludeStrongLifetimeRAII Strong(Policy);

1469

1470 if (T->isReadOnly())

1471 OS << "read_only ";

1472 else

1473 OS << "write_only ";

1474 OS << "pipe ";

1475 print(T->getElementType(), OS, StringRef());

1476 spaceBeforePlaceHolder(OS);

1477}

1478

1479void TypePrinter::printPipeAfter(const PipeType *T, raw_ostream &OS) {}

1480

1481void TypePrinter::printBitIntBefore(const BitIntType *T, raw_ostream &OS) {

1482 if (T->isUnsigned())

1483 OS << "unsigned ";

1484 OS << "_BitInt(" << T->getNumBits() << ")";

1485 spaceBeforePlaceHolder(OS);

1486}

1487

1488void TypePrinter::printBitIntAfter(const BitIntType *T, raw_ostream &OS) {}

1489

1490void TypePrinter::printDependentBitIntBefore(const DependentBitIntType *T,

1491 raw_ostream &OS) {

1492 if (T->isUnsigned())

1493 OS << "unsigned ";

1494 OS << "_BitInt(";

1495 T->getNumBitsExpr()->printPretty(OS, nullptr, Policy);

1496 OS << ")";

1497 spaceBeforePlaceHolder(OS);

1498}

1499

1500void TypePrinter::printDependentBitIntAfter(const DependentBitIntType *T,

1501 raw_ostream &OS) {}

1502

1503void TypePrinter::printPredefinedSugarBefore(const PredefinedSugarType *T,

1504 raw_ostream &OS) {

1505 OS << T->getIdentifier()->getName();

1506 spaceBeforePlaceHolder(OS);

1507}

1508

1509void TypePrinter::printPredefinedSugarAfter(const PredefinedSugarType *T,

1510 raw_ostream &OS) {}

1511

1512void TypePrinter::printTagType(const TagType *T, raw_ostream &OS) {

1513 TagDecl *D = T->getDecl();

1514

1516 D->print(OS, Policy, Indentation);

1517 spaceBeforePlaceHolder(OS);

1518 return;

1519 }

1520

1521 bool HasKindDecoration = false;

1522

1525 HasKindDecoration = true;

1527 OS << ' ';

1528 }

1529 } else {

1530 OS << TypeWithKeyword::getKeywordName(T->getKeyword());

1531 if (T->getKeyword() != ElaboratedTypeKeyword::None)

1532 OS << ' ';

1533 }

1534

1536 T->getQualifier().print(OS, Policy);

1538

1539

1540

1542 }

1543

1544 if (const IdentifierInfo *II = D->getIdentifier())

1547 assert(Typedef->getIdentifier() && "Typedef without identifier?");

1548 OS << Typedef->getIdentifier()->getName();

1549 } else {

1550

1551

1553

1555 OS << "lambda";

1556 HasKindDecoration = true;

1558 OS << "anonymous";

1559 } else {

1560 OS << "unnamed";

1561 }

1562

1564

1565

1566

1567 if (!HasKindDecoration)

1569

1573 OS << " at ";

1575 llvm::SmallString<1024> WrittenFile(File);

1576 if (auto *Callbacks = Policy.Callbacks)

1577 WrittenFile = Callbacks->remapPath(File);

1578

1579

1580

1581 llvm::sys::path::Style Style =

1582 llvm::sys::path::is_absolute(WrittenFile)

1583 ? llvm::sys::path::Style::native

1585 ? llvm::sys::path::Style::windows_backslash

1586 : llvm::sys::path::Style::posix);

1587 llvm::sys::path::native(WrittenFile, Style);

1588 OS << WrittenFile << ':' << PLoc.getLine() << ':' << PLoc.getColumn();

1589 }

1590 }

1591

1593 }

1594

1595

1596

1597 if (auto *S = dyn_cast(D)) {

1598 const TemplateParameterList *TParams =

1599 S->getSpecializedTemplate()->getTemplateParameters();

1600 const ASTTemplateArgumentListInfo *TArgAsWritten =

1601 S->getTemplateArgsAsWritten();

1602 IncludeStrongLifetimeRAII Strong(Policy);

1604 printTemplateArgumentList(OS, TArgAsWritten->arguments(), Policy,

1605 TParams);

1606 else

1607 printTemplateArgumentList(OS, S->getTemplateArgs().asArray(), Policy,

1608 TParams);

1609 }

1610

1611 spaceBeforePlaceHolder(OS);

1612}

1613

1614void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {

1615

1617 for (const auto *PNA : T->getDecl()

1618 ->getMostRecentDecl()

1619 ->specific_attrs()) {

1620 if (declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(),

1621 T->getDecl()))

1622 continue;

1623

1624 QualType T = PNA->getTypedefType();

1625 while (true) {

1626 if (auto *TT = dyn_cast(T))

1627 return printTypeSpec(TT->getDecl(), OS);

1628 if (auto *TST = dyn_cast(T))

1629 return printTemplateId(TST, OS, true);

1631 }

1632 }

1633 }

1634

1635 printTagType(T, OS);

1636}

1637

1638void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}

1639

1640void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {

1641 printTagType(T, OS);

1642}

1643

1644void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}

1645

1646void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,

1647 raw_ostream &OS) {

1648 const ASTContext &Ctx = T->getDecl()->getASTContext();

1649 IncludeStrongLifetimeRAII Strong(Policy);

1650 T->getTemplateName(Ctx).print(OS, Policy);

1652 auto *Decl = T->getDecl();

1653

1654

1655 if (auto *RD = dyn_cast(Decl)) {

1656 printTemplateArgumentList(OS, RD->getTemplateArgsAsWritten()->arguments(),

1657 Policy,

1658 T->getTemplateDecl()->getTemplateParameters());

1659 } else {

1660 ClassTemplateDecl *TD = Decl->getDescribedClassTemplate();

1661 assert(TD);

1662 printTemplateArgumentList(

1664 T->getTemplateDecl()->getTemplateParameters());

1665 }

1666 }

1667 spaceBeforePlaceHolder(OS);

1668}

1669

1670void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,

1671 raw_ostream &OS) {}

1672

1673void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,

1674 raw_ostream &OS) {

1675 TemplateTypeParmDecl *D = T->getDecl();

1678 TC->print(OS, Policy);

1679 OS << ' ';

1680 }

1681 OS << "auto";

1682 } else if (IdentifierInfo *Id = T->getIdentifier())

1684 : Id->getName());

1685 else

1686 OS << "type-parameter-" << T->getDepth() << '-' << T->getIndex();

1687

1688 spaceBeforePlaceHolder(OS);

1689}

1690

1691void TypePrinter::printTemplateTypeParmAfter(const TemplateTypeParmType *T,

1692 raw_ostream &OS) {}

1693

1694void TypePrinter::printSubstTemplateTypeParmBefore(

1695 const SubstTemplateTypeParmType *T,

1696 raw_ostream &OS) {

1697 IncludeStrongLifetimeRAII Strong(Policy);

1698 printBefore(T->getReplacementType(), OS);

1699}

1700

1701void TypePrinter::printSubstTemplateTypeParmAfter(

1702 const SubstTemplateTypeParmType *T,

1703 raw_ostream &OS) {

1704 IncludeStrongLifetimeRAII Strong(Policy);

1705 printAfter(T->getReplacementType(), OS);

1706}

1707

1708void TypePrinter::printSubstBuiltinTemplatePackBefore(

1709 const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {

1710 IncludeStrongLifetimeRAII Strong(Policy);

1711 OS << "type-pack";

1712}

1713

1714void TypePrinter::printSubstBuiltinTemplatePackAfter(

1715 const SubstBuiltinTemplatePackType *T, raw_ostream &OS) {}

1716

1717void TypePrinter::printSubstTemplateTypeParmPackBefore(

1718 const SubstTemplateTypeParmPackType *T,

1719 raw_ostream &OS) {

1720 IncludeStrongLifetimeRAII Strong(Policy);

1721 if (const TemplateTypeParmDecl *D = T->getReplacedParameter()) {

1724 TC->print(OS, Policy);

1725 OS << ' ';

1726 }

1727 OS << "auto";

1728 } else if (IdentifierInfo *Id = D->getIdentifier())

1730 : Id->getName());

1731 else

1733

1734 spaceBeforePlaceHolder(OS);

1735 }

1736}

1737

1738void TypePrinter::printSubstTemplateTypeParmPackAfter(

1739 const SubstTemplateTypeParmPackType *T,

1740 raw_ostream &OS) {

1741 IncludeStrongLifetimeRAII Strong(Policy);

1742}

1743

1744void TypePrinter::printTemplateId(const TemplateSpecializationType *T,

1745 raw_ostream &OS, bool FullyQualify) {

1746 IncludeStrongLifetimeRAII Strong(Policy);

1747

1749 K != ElaboratedTypeKeyword::None)

1750 OS << TypeWithKeyword::getKeywordName(K) << ' ';

1751

1752 TemplateDecl *TD =

1753 T->getTemplateName().getAsTemplateDecl(true);

1754

1755 if (FullyQualify && TD) {

1758

1760 } else {

1761 T->getTemplateName().print(OS, Policy,

1763 ? TemplateName::Qualified::AsWritten

1764 : TemplateName::Qualified::None);

1765 }

1766

1767 DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);

1769 printTemplateArgumentList(OS, T->template_arguments(), Policy, TPL);

1770 spaceBeforePlaceHolder(OS);

1771}

1772

1773void TypePrinter::printTemplateSpecializationBefore(

1774 const TemplateSpecializationType *T,

1775 raw_ostream &OS) {

1777}

1778

1779void TypePrinter::printTemplateSpecializationAfter(

1780 const TemplateSpecializationType *T,

1781 raw_ostream &OS) {}

1782

1783void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {

1784 if (!HasEmptyPlaceHolder && isa<FunctionType>(T->getInnerType())) {

1785 printBefore(T->getInnerType(), OS);

1786 OS << '(';

1787 } else

1788 printBefore(T->getInnerType(), OS);

1789}

1790

1791void TypePrinter::printParenAfter(const ParenType *T, raw_ostream &OS) {

1792 if (!HasEmptyPlaceHolder && isa<FunctionType>(T->getInnerType())) {

1793 OS << ')';

1794 printAfter(T->getInnerType(), OS);

1795 } else

1796 printAfter(T->getInnerType(), OS);

1797}

1798

1799void TypePrinter::printDependentNameBefore(const DependentNameType *T,

1800 raw_ostream &OS) {

1801 OS << TypeWithKeyword::getKeywordName(T->getKeyword());

1802 if (T->getKeyword() != ElaboratedTypeKeyword::None)

1803 OS << " ";

1804 T->getQualifier().print(OS, Policy);

1805 OS << T->getIdentifier()->getName();

1806 spaceBeforePlaceHolder(OS);

1807}

1808

1809void TypePrinter::printDependentNameAfter(const DependentNameType *T,

1810 raw_ostream &OS) {}

1811

1812void TypePrinter::printPackExpansionBefore(const PackExpansionType *T,

1813 raw_ostream &OS) {

1814 printBefore(T->getPattern(), OS);

1815}

1816

1817void TypePrinter::printPackExpansionAfter(const PackExpansionType *T,

1818 raw_ostream &OS) {

1819 printAfter(T->getPattern(), OS);

1820 OS << "...";

1821}

1822

1824 raw_ostream &OS,

1826 OS << ' ';

1827 if (T->isCountInBytes() && T->isOrNull())

1828 OS << "__sized_by_or_null(";

1829 else if (T->isCountInBytes())

1830 OS << "__sized_by(";

1831 else if (T->isOrNull())

1832 OS << "__counted_by_or_null(";

1833 else

1834 OS << "__counted_by(";

1835 if (T->getCountExpr())

1836 T->getCountExpr()->printPretty(OS, nullptr, Policy);

1837 OS << ')';

1838}

1839

1840void TypePrinter::printCountAttributedBefore(const CountAttributedType *T,

1841 raw_ostream &OS) {

1842 printBefore(T->desugar(), OS);

1845}

1846

1847void TypePrinter::printCountAttributedAfter(const CountAttributedType *T,

1848 raw_ostream &OS) {

1849 printAfter(T->desugar(), OS);

1852}

1853

1854void TypePrinter::printAttributedBefore(const AttributedType *T,

1855 raw_ostream &OS) {

1856

1857

1858

1859 if (T->getAttrKind() == attr::ObjCGC ||

1860 T->getAttrKind() == attr::ObjCOwnership)

1861 return printBefore(T->getEquivalentType(), OS);

1862

1863 if (T->getAttrKind() == attr::ObjCKindOf)

1864 OS << "__kindof ";

1865

1866 if (T->getAttrKind() == attr::PreserveNone) {

1867 OS << "__attribute__((preserve_none)) ";

1868 spaceBeforePlaceHolder(OS);

1869 } else if (T->getAttrKind() == attr::PreserveMost) {

1870 OS << "__attribute__((preserve_most)) ";

1871 spaceBeforePlaceHolder(OS);

1872 } else if (T->getAttrKind() == attr::PreserveAll) {

1873 OS << "__attribute__((preserve_all)) ";

1874 spaceBeforePlaceHolder(OS);

1875 }

1876

1877 if (T->getAttrKind() == attr::AddressSpace)

1878 printBefore(T->getEquivalentType(), OS);

1879 else

1880 printBefore(T->getModifiedType(), OS);

1881

1882 if (T->isMSTypeSpec()) {

1883 switch (T->getAttrKind()) {

1884 default: return;

1885 case attr::Ptr32: OS << " __ptr32"; break;

1886 case attr::Ptr64: OS << " __ptr64"; break;

1887 case attr::SPtr: OS << " __sptr"; break;

1888 case attr::UPtr: OS << " __uptr"; break;

1889 }

1890 spaceBeforePlaceHolder(OS);

1891 }

1892

1893 if (T->isWebAssemblyFuncrefSpec())

1894 OS << "__funcref";

1895

1896

1897 if (T->getImmediateNullability()) {

1898 if (T->getAttrKind() == attr::TypeNonNull)

1899 OS << " _Nonnull";

1900 else if (T->getAttrKind() == attr::TypeNullable)

1901 OS << " _Nullable";

1902 else if (T->getAttrKind() == attr::TypeNullUnspecified)

1903 OS << " _Null_unspecified";

1904 else if (T->getAttrKind() == attr::TypeNullableResult)

1905 OS << " _Nullable_result";

1906 else

1907 llvm_unreachable("unhandled nullability");

1908 spaceBeforePlaceHolder(OS);

1909 }

1910}

1911

1912void TypePrinter::printAttributedAfter(const AttributedType *T,

1913 raw_ostream &OS) {

1914

1915

1916

1917 if (T->getAttrKind() == attr::ObjCGC ||

1918 T->getAttrKind() == attr::ObjCOwnership)

1919 return printAfter(T->getEquivalentType(), OS);

1920

1921

1922

1923 SaveAndRestore MaybeSuppressCC(InsideCCAttribute, T->isCallingConv());

1924

1925 printAfter(T->getModifiedType(), OS);

1926

1927

1928

1929 if (T->getAttrKind() == attr::ObjCKindOf || T->isMSTypeSpec() ||

1930 T->getImmediateNullability() || T->isWebAssemblyFuncrefSpec())

1931 return;

1932

1933

1934 if (T->getAttrKind() == attr::ObjCInertUnsafeUnretained)

1935 return;

1936

1937

1938 if (T->getAttrKind() == attr::NSReturnsRetained &&

1939 T->getEquivalentType()->castAs()

1940 ->getExtInfo().getProducesResult())

1941 return;

1942

1943 if (T->getAttrKind() == attr::LifetimeBound) {

1944 OS << " [[clang::lifetimebound]]";

1945 return;

1946 }

1947 if (T->getAttrKind() == attr::LifetimeCaptureBy) {

1948 OS << " [[clang::lifetime_capture_by(";

1949 if (auto *attr = dyn_cast_or_null(T->getAttr()))

1950 llvm::interleaveComma(attr->getArgIdents(), OS,

1951 [&](auto it) { OS << it->getName(); });

1952 OS << ")]]";

1953 return;

1954 }

1955

1956

1957

1958

1959 if (T->getAttrKind() == attr::AddressSpace)

1960 return;

1961

1962 if (T->getAttrKind() == attr::AnnotateType) {

1963

1964

1965

1966

1967 OS << " [[clang::annotate_type(...)]]";

1968 return;

1969 }

1970

1971 if (T->getAttrKind() == attr::ArmStreaming) {

1972 OS << "__arm_streaming";

1973 return;

1974 }

1975 if (T->getAttrKind() == attr::ArmStreamingCompatible) {

1976 OS << "__arm_streaming_compatible";

1977 return;

1978 }

1979

1980 if (T->getAttrKind() == attr::SwiftAttr) {

1981 if (auto *swiftAttr = dyn_cast_or_null(T->getAttr())) {

1982 OS << " __attribute__((swift_attr(\"" << swiftAttr->getAttribute()

1983 << "\")))";

1984 }

1985 return;

1986 }

1987

1988 if (T->getAttrKind() == attr::PreserveAll ||

1989 T->getAttrKind() == attr::PreserveMost ||

1990 T->getAttrKind() == attr::PreserveNone) {

1991

1992 return;

1993 }

1994

1995 OS << " __attribute__((";

1996 switch (T->getAttrKind()) {

1997#define TYPE_ATTR(NAME)

1998#define DECL_OR_TYPE_ATTR(NAME)

1999#define ATTR(NAME) case attr::NAME:

2000#include "clang/Basic/AttrList.inc"

2001 llvm_unreachable("non-type attribute attached to type");

2002

2003 case attr::BTFTypeTag:

2004 llvm_unreachable("BTFTypeTag attribute handled separately");

2005

2006 case attr::HLSLResourceClass:

2007 case attr::HLSLROV:

2008 case attr::HLSLRawBuffer:

2009 case attr::HLSLContainedType:

2010 case attr::HLSLIsCounter:

2011 llvm_unreachable("HLSL resource type attributes handled separately");

2012

2013 case attr::OpenCLPrivateAddressSpace:

2014 case attr::OpenCLGlobalAddressSpace:

2015 case attr::OpenCLGlobalDeviceAddressSpace:

2016 case attr::OpenCLGlobalHostAddressSpace:

2017 case attr::OpenCLLocalAddressSpace:

2018 case attr::OpenCLConstantAddressSpace:

2019 case attr::OpenCLGenericAddressSpace:

2020 case attr::HLSLGroupSharedAddressSpace:

2021

2022

2023 break;

2024

2025 case attr::CountedBy:

2026 case attr::CountedByOrNull:

2027 case attr::SizedBy:

2028 case attr::SizedByOrNull:

2029 case attr::LifetimeBound:

2030 case attr::LifetimeCaptureBy:

2031 case attr::TypeNonNull:

2032 case attr::TypeNullable:

2033 case attr::TypeNullableResult:

2034 case attr::TypeNullUnspecified:

2035 case attr::ObjCGC:

2036 case attr::ObjCInertUnsafeUnretained:

2037 case attr::ObjCKindOf:

2038 case attr::ObjCOwnership:

2039 case attr::Ptr32:

2040 case attr::Ptr64:

2041 case attr::SPtr:

2042 case attr::UPtr:

2043 case attr::PointerAuth:

2044 case attr::AddressSpace:

2045 case attr::CmseNSCall:

2046 case attr::AnnotateType:

2047 case attr::WebAssemblyFuncref:

2048 case attr::ArmAgnostic:

2049 case attr::ArmStreaming:

2050 case attr::ArmStreamingCompatible:

2051 case attr::ArmIn:

2052 case attr::ArmOut:

2053 case attr::ArmInOut:

2054 case attr::ArmPreserves:

2055 case attr::NonBlocking:

2056 case attr::NonAllocating:

2057 case attr::Blocking:

2058 case attr::Allocating:

2059 case attr::SwiftAttr:

2060 case attr::PreserveAll:

2061 case attr::PreserveMost:

2062 case attr::PreserveNone:

2063 llvm_unreachable("This attribute should have been handled already");

2064

2065 case attr::NSReturnsRetained:

2066 OS << "ns_returns_retained";

2067 break;

2068

2069

2070

2071 case attr::AnyX86NoCfCheck: OS << "nocf_check"; break;

2072 case attr::CDecl: OS << "cdecl"; break;

2073 case attr::FastCall: OS << "fastcall"; break;

2074 case attr::StdCall: OS << "stdcall"; break;

2075 case attr::ThisCall: OS << "thiscall"; break;

2076 case attr::SwiftCall: OS << "swiftcall"; break;

2077 case attr::SwiftAsyncCall: OS << "swiftasynccall"; break;

2078 case attr::VectorCall: OS << "vectorcall"; break;

2079 case attr::Pascal: OS << "pascal"; break;

2080 case attr::MSABI: OS << "ms_abi"; break;

2081 case attr::SysVABI: OS << "sysv_abi"; break;

2082 case attr::RegCall: OS << "regcall"; break;

2083 case attr::Pcs: {

2084 OS << "pcs(";

2085 QualType t = T->getEquivalentType();

2088 OS << (t->castAs()->getCallConv() == CC_AAPCS ?

2089 "\"aapcs\"" : "\"aapcs-vfp\"");

2090 OS << ')';

2091 break;

2092 }

2093 case attr::AArch64VectorPcs: OS << "aarch64_vector_pcs"; break;

2094 case attr::AArch64SVEPcs: OS << "aarch64_sve_pcs"; break;

2095 case attr::IntelOclBicc:

2096 OS << "inteloclbicc";

2097 break;

2098 case attr::M68kRTD:

2099 OS << "m68k_rtd";

2100 break;

2101 case attr::RISCVVectorCC:

2102 OS << "riscv_vector_cc";

2103 break;

2104 case attr::RISCVVLSCC:

2105 OS << "riscv_vls_cc";

2106 break;

2107 case attr::NoDeref:

2108 OS << "noderef";

2109 break;

2110 case attr::CFIUncheckedCallee:

2111 OS << "cfi_unchecked_callee";

2112 break;

2113 case attr::AcquireHandle:

2114 OS << "acquire_handle";

2115 break;

2116 case attr::ArmMveStrictPolymorphism:

2117 OS << "__clang_arm_mve_strict_polymorphism";

2118 break;

2119 case attr::ExtVectorType:

2120 OS << "ext_vector_type";

2121 break;

2122 case attr::CFISalt:

2124 break;

2125 }

2126 OS << "))";

2127}

2128

2129void TypePrinter::printBTFTagAttributedBefore(const BTFTagAttributedType *T,

2130 raw_ostream &OS) {

2131 printBefore(T->getWrappedType(), OS);

2132 OS << " __attribute__((btf_type_tag(\"" << T->getAttr()->getBTFTypeTag() << "\")))";

2133}

2134

2135void TypePrinter::printBTFTagAttributedAfter(const BTFTagAttributedType *T,

2136 raw_ostream &OS) {

2137 printAfter(T->getWrappedType(), OS);

2138}

2139

2140void TypePrinter::printHLSLAttributedResourceBefore(

2141 const HLSLAttributedResourceType *T, raw_ostream &OS) {

2142 printBefore(T->getWrappedType(), OS);

2143}

2144

2145void TypePrinter::printHLSLAttributedResourceAfter(

2146 const HLSLAttributedResourceType *T, raw_ostream &OS) {

2147 printAfter(T->getWrappedType(), OS);

2148 const HLSLAttributedResourceType::Attributes &Attrs = T->getAttrs();

2149 OS << " [[hlsl::resource_class("

2150 << HLSLResourceClassAttr::ConvertResourceClassToStr(Attrs.ResourceClass)

2151 << ")]]";

2152 if (Attrs.IsROV)

2153 OS << " [[hlsl::is_rov]]";

2154 if (Attrs.RawBuffer)

2155 OS << " [[hlsl::raw_buffer]]";

2156 if (Attrs.IsCounter)

2157 OS << " [[hlsl::is_counter]]";

2158

2159 QualType ContainedTy = T->getContainedType();

2160 if (!ContainedTy.isNull()) {

2161 OS << " [[hlsl::contained_type(";

2162 printBefore(ContainedTy, OS);

2163 printAfter(ContainedTy, OS);

2164 OS << ")]]";

2165 }

2166}

2167

2168void TypePrinter::printHLSLInlineSpirvBefore(const HLSLInlineSpirvType *T,

2169 raw_ostream &OS) {

2170 OS << "__hlsl_spirv_type<" << T->getOpcode();

2171

2172 OS << ", " << T->getSize();

2173 OS << ", " << T->getAlignment();

2174

2175 for (auto &Operand : T->getOperands()) {

2176 using SpirvOperandKind = SpirvOperand::SpirvOperandKind;

2177

2178 OS << ", ";

2179 switch (Operand.getKind()) {

2180 case SpirvOperandKind::ConstantId: {

2181 QualType ConstantType = Operand.getResultType();

2182 OS << "vk::integral_constant<";

2183 printBefore(ConstantType, OS);

2184 printAfter(ConstantType, OS);

2185 OS << ", ";

2187 OS << ">";

2188 break;

2189 }

2190 case SpirvOperandKind::Literal:

2191 OS << "vk::Literal<vk::integral_constant<uint, ";

2193 OS << ">>";

2194 break;

2195 case SpirvOperandKind::TypeId: {

2196 QualType Type = Operand.getResultType();

2197 printBefore(Type, OS);

2198 printAfter(Type, OS);

2199 break;

2200 }

2201 default:

2202 llvm_unreachable("Invalid SpirvOperand kind!");

2203 break;

2204 }

2205 }

2206

2207 OS << ">";

2208}

2209

2210void TypePrinter::printHLSLInlineSpirvAfter(const HLSLInlineSpirvType *T,

2211 raw_ostream &OS) {

2212

2213}

2214

2215void TypePrinter::printObjCInterfaceBefore(const ObjCInterfaceType *T,

2216 raw_ostream &OS) {

2217 OS << T->getDecl()->getName();

2218 spaceBeforePlaceHolder(OS);

2219}

2220

2221void TypePrinter::printObjCInterfaceAfter(const ObjCInterfaceType *T,

2222 raw_ostream &OS) {}

2223

2224void TypePrinter::printObjCTypeParamBefore(const ObjCTypeParamType *T,

2225 raw_ostream &OS) {

2226 OS << T->getDecl()->getName();

2227 if (T->qual_empty()) {

2228 bool isFirst = true;

2229 OS << '<';

2230 for (const auto *I : T->quals()) {

2231 if (isFirst)

2232 isFirst = false;

2233 else

2234 OS << ',';

2235 OS << I->getName();

2236 }

2237 OS << '>';

2238 }

2239

2240 spaceBeforePlaceHolder(OS);

2241}

2242

2243void TypePrinter::printObjCTypeParamAfter(const ObjCTypeParamType *T,

2244 raw_ostream &OS) {}

2245

2246void TypePrinter::printObjCObjectBefore(const ObjCObjectType *T,

2247 raw_ostream &OS) {

2248 if (T->qual_empty() && T->isUnspecializedAsWritten() &&

2249 T->isKindOfTypeAsWritten())

2250 return printBefore(T->getBaseType(), OS);

2251

2252 if (T->isKindOfTypeAsWritten())

2253 OS << "__kindof ";

2254

2255 print(T->getBaseType(), OS, StringRef());

2256

2257 if (T->isSpecializedAsWritten()) {

2258 bool isFirst = true;

2259 OS << '<';

2260 for (auto typeArg : T->getTypeArgsAsWritten()) {

2261 if (isFirst)

2262 isFirst = false;

2263 else

2264 OS << ",";

2265

2266 print(typeArg, OS, StringRef());

2267 }

2268 OS << '>';

2269 }

2270

2271 if (T->qual_empty()) {

2272 bool isFirst = true;

2273 OS << '<';

2274 for (const auto *I : T->quals()) {

2275 if (isFirst)

2276 isFirst = false;

2277 else

2278 OS << ',';

2279 OS << I->getName();

2280 }

2281 OS << '>';

2282 }

2283

2284 spaceBeforePlaceHolder(OS);

2285}

2286

2287void TypePrinter::printObjCObjectAfter(const ObjCObjectType *T,

2288 raw_ostream &OS) {

2289 if (T->qual_empty() && T->isUnspecializedAsWritten() &&

2290 T->isKindOfTypeAsWritten())

2291 return printAfter(T->getBaseType(), OS);

2292}

2293

2294void TypePrinter::printObjCObjectPointerBefore(const ObjCObjectPointerType *T,

2295 raw_ostream &OS) {

2297

2298

2301 if (HasEmptyPlaceHolder)

2302 OS << ' ';

2303 OS << '*';

2304 }

2305}

2306

2307void TypePrinter::printObjCObjectPointerAfter(const ObjCObjectPointerType *T,

2308 raw_ostream &OS) {}

2309

2310static

2312

2316

2318 llvm::raw_ostream &OS, bool IncludeType) {

2319 A.print(PP, OS, IncludeType);

2320}

2321

2324 bool IncludeType) {

2329}

2330

2332 TemplateArgument Pattern,

2333 ArrayRef Args,

2334 unsigned Depth);

2335

2339 return true;

2340

2341

2342 if (auto *TTPT = Pattern->getAsCanonical()) {

2343 if (TTPT->getDepth() == Depth && TTPT->getIndex() < Args.size() &&

2346 Args[TTPT->getIndex()].getAsType(), Pattern.getQualifiers());

2348 }

2349 return false;

2350 }

2351

2352

2353

2354

2358 if (TQual != PatQual)

2359 return false;

2360

2361

2362 {

2363 QualType TPointee = T->getPointeeType();

2365 if (!TPointee.isNull() && !PPointee.isNull())

2366 return T->getTypeClass() == Pattern->getTypeClass() &&

2368 }

2369

2370

2371 if (auto *PTST =

2375 if (auto *TTST = T->getAs()) {

2376 Template = TTST->getTemplateName();

2377 TemplateArgs = TTST->template_arguments();

2378 } else if (auto *CTSD = dyn_cast_or_null(

2379 T->getAsCXXRecordDecl())) {

2381 TemplateArgs = CTSD->getTemplateArgs().asArray();

2382 } else {

2383 return false;

2384 }

2385

2387 Args, Depth))

2388 return false;

2389 if (TemplateArgs.size() != PTST->template_arguments().size())

2390 return false;

2391 for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)

2393 Ctx, TemplateArgs[I], PTST->template_arguments()[I], Args, Depth))

2394 return false;

2395 return true;

2396 }

2397

2398

2399 return false;

2400}

2401

2402

2403

2408 return false;

2409

2410

2414 return false;

2415

2419

2423 return false;

2424

2427 }

2428

2429 return false;

2430}

2431

2435 unsigned Depth) {

2439 return true;

2440

2442 if (auto *DRE =

2444 if (auto *NTTP = dyn_cast(DRE->getDecl()))

2445 return NTTP->getDepth() == Depth && Args.size() > NTTP->getIndex() &&

2446 Args[NTTP->getIndex()].structurallyEquals(Arg);

2447 }

2448 }

2449

2451 return true;

2452

2454 return false;

2455

2458 Depth);

2459

2462 if (auto *TTPD = dyn_cast_or_null(PatTD))

2463 return TTPD->getDepth() == Depth && Args.size() > TTPD->getIndex() &&

2466 }

2467

2468

2469 return false;

2470}

2471

2472bool clang::isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg,

2473 const NamedDecl *Param,

2474 ArrayRef Args,

2475 unsigned Depth) {

2476

2478 return true;

2479

2480 if (auto *TTPD = dyn_cast(Param)) {

2481 return TTPD->hasDefaultArgument() &&

2483 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);

2484 } else if (auto *TTPD = dyn_cast(Param)) {

2485 return TTPD->hasDefaultArgument() &&

2487 Ctx, Arg, TTPD->getDefaultArgument().getArgument(), Args, Depth);

2488 } else if (auto *NTTPD = dyn_cast(Param)) {

2489 return NTTPD->hasDefaultArgument() &&

2491 Ctx, Arg, NTTPD->getDefaultArgument().getArgument(), Args,

2492 Depth);

2493 }

2494 return false;

2495}

2496

2497template

2498static void

2501

2503 !Args.empty() && !IsPack && Args.size() <= TPL->size()) {

2505 for (const TA &A : Args)

2507 while (!Args.empty() && getArgument(Args.back()).getIsDefaulted())

2508 Args = Args.drop_back();

2509 }

2510

2511 const char *Comma = Policy.MSVCFormatting ? "," : ", ";

2512 if (!IsPack)

2513 OS << '<';

2514

2515 bool NeedSpace = false;

2516 bool FirstArg = true;

2517 for (const auto &Arg : Args) {

2518

2520 llvm::raw_svector_ostream ArgOS(Buf);

2523 if (Argument.pack_size() && !FirstArg)

2524 OS << Comma;

2526 true, ParmIndex);

2527 } else {

2528 if (!FirstArg)

2529 OS << Comma;

2530

2533 Policy, TPL, ParmIndex));

2534 }

2535 StringRef ArgString = ArgOS.str();

2536

2537

2538

2539

2540 if (FirstArg && ArgString.starts_with(":"))

2541 OS << ' ';

2542

2543 OS << ArgString;

2544

2545

2546

2547 if (!ArgString.empty()) {

2549 FirstArg = false;

2550 }

2551

2552

2553 if (!IsPack)

2554 ParmIndex++;

2555 }

2556

2557 if (!IsPack) {

2558 if (NeedSpace)

2559 OS << ' ';

2560 OS << '>';

2561 }

2562}

2563

2564void clang::printTemplateArgumentList(raw_ostream &OS,

2565 const TemplateArgumentListInfo &Args,

2566 const PrintingPolicy &Policy,

2567 const TemplateParameterList *TPL) {

2568 printTemplateArgumentList(OS, Args.arguments(), Policy, TPL);

2569}

2570

2571void clang::printTemplateArgumentList(raw_ostream &OS,

2572 ArrayRef Args,

2573 const PrintingPolicy &Policy,

2574 const TemplateParameterList *TPL) {

2575 PrintingPolicy InnerPolicy = Policy;

2577 printTo(OS, Args, InnerPolicy, TPL, false, 0);

2578}

2579

2580void clang::printTemplateArgumentList(raw_ostream &OS,

2581 ArrayRef Args,

2582 const PrintingPolicy &Policy,

2583 const TemplateParameterList *TPL) {

2584 PrintingPolicy InnerPolicy = Policy;

2586 printTo(OS, Args, InnerPolicy, TPL, false, 0);

2587}

2588

2593

2596 llvm::raw_svector_ostream StrOS(Buf);

2597 print(StrOS, P);

2598 return StrOS.str().str();

2599}

2600

2604

2608 return;

2609

2610 OS << "__ptrauth(";

2614}

2615

2620

2621

2622

2623

2626 llvm::raw_svector_ostream StrOS(Buf);

2627 print(StrOS, Policy);

2628 return std::string(StrOS.str());

2629}

2630

2633 return false;

2634

2636 return false;

2637

2639 return false;

2640

2643 return false;

2644

2646 PointerAuth && !PointerAuth.isEmptyWhenPrinted(Policy))

2647 return false;

2648

2649 return true;

2650}

2651

2653 switch (AS) {

2655 return "";

2658 return "__global";

2661 return "__local";

2664 return "__private";

2666 return "__constant";

2668 return "__generic";

2671 return "__global_device";

2674 return "__global_host";

2676 return "__device__";

2678 return "__constant__";

2680 return "__shared__";

2682 return "__sptr __ptr32";

2684 return "__uptr __ptr32";

2686 return "__ptr64";

2688 return "groupshared";

2690 return "hlsl_constant";

2692 return "hlsl_private";

2694 return "hlsl_device";

2696 return "hlsl_input";

2698 return "__funcref";

2699 default:

2701 }

2702}

2703

2704

2705

2706

2708 bool appendSpaceIfNonEmpty) const {

2709 bool addSpace = false;

2710

2712 if (quals) {

2714 addSpace = true;

2715 }

2717 if (addSpace)

2718 OS << ' ';

2719 OS << "__unaligned";

2720 addSpace = true;

2721 }

2723 if (!ASStr.empty()) {

2724 if (addSpace)

2725 OS << ' ';

2726 addSpace = true;

2727

2729 OS << "__attribute__((address_space(" << ASStr << ")))";

2730 else

2731 OS << ASStr;

2732 }

2733

2735 if (addSpace)

2736 OS << ' ';

2737 addSpace = true;

2739 OS << "__weak";

2740 else

2741 OS << "__strong";

2742 }

2745 if (addSpace)

2746 OS << ' ';

2747 addSpace = true;

2748 }

2749

2750 switch (lifetime) {

2755 OS << "__strong";

2756 break;

2757

2760 }

2761 }

2762

2764 if (addSpace)

2765 OS << ' ';

2766 addSpace = true;

2767

2768 PointerAuth.print(OS, Policy);

2769 }

2770

2771 if (appendSpaceIfNonEmpty && addSpace)

2772 OS << ' ';

2773}

2774

2778

2780 std::string S;

2782 return S;

2783}

2784

2787 std::string buffer;

2789 return buffer;

2790}

2791

2793 const Twine &PlaceHolder, unsigned Indentation) const {

2795 Indentation);

2796}

2797

2800 const Twine &PlaceHolder, unsigned Indentation) {

2802 StringRef PH = PlaceHolder.toStringRef(PHBuf);

2803

2804 TypePrinter(policy, Indentation).print(ty, qs, OS, PH);

2805}

2806

2812

2814 std::string &buffer,

2817 llvm::raw_svector_ostream StrOS(Buf);

2818 TypePrinter(policy).print(ty, qs, StrOS, buffer);

2819 std::string str = std::string(StrOS.str());

2820 buffer.swap(str);

2821}

2822

Defines the clang::ASTContext interface.

Provides definitions for the various language-specific address spaces.

Defines the clang::attr::Kind enum.

Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....

Defines the C++ template declaration subclasses.

Defines the ExceptionSpecificationType enumeration and various utility functions.

Defines the clang::IdentifierInfo, clang::IdentifierTable, and clang::Selector interfaces.

static void print(llvm::raw_ostream &OS, const T &V, ASTContext &ASTCtx, QualType Ty)

#define CC_VLS_CASE(ABI_VLEN)

Forward-declares and imports various common LLVM datatypes that clang wants to use unqualified.

Defines the clang::LangOptions interface.

Defines the clang::SourceLocation class and associated facilities.

Defines the SourceManager interface.

Defines various enumerations that describe declaration and type specifiers.

static void printHLSLMatrixBefore(TypePrinter &TP, const ConstantMatrixType *T, raw_ostream &OS)

Definition TypePrinter.cpp:851

static void printTo(raw_ostream &OS, ArrayRef< TA > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex)

Definition TypePrinter.cpp:2499

static const TemplateArgument & getArgument(const TemplateArgument &A)

Definition TypePrinter.cpp:2311

static bool isSubstitutedType(ASTContext &Ctx, QualType T, QualType Pattern, ArrayRef< TemplateArgument > Args, unsigned Depth)

Definition TypePrinter.cpp:2336

static void printArgument(const TemplateArgument &A, const PrintingPolicy &PP, llvm::raw_ostream &OS, bool IncludeType)

Definition TypePrinter.cpp:2317

static QualType skipTopLevelReferences(QualType T)

Definition TypePrinter.cpp:439

static void printClangMatrixBefore(TypePrinter &TP, const ConstantMatrixType *T, raw_ostream &OS)

Definition TypePrinter.cpp:863

static void printDims(const ConstantMatrixType *T, raw_ostream &OS)

Definition TypePrinter.cpp:847

static void printHLSLMatrixAfter(const ConstantMatrixType *T, raw_ostream &OS)

Definition TypePrinter.cpp:857

static void printCountAttributedImpl(const CountAttributedType *T, raw_ostream &OS, const PrintingPolicy &Policy)

Definition TypePrinter.cpp:1823

static SplitQualType splitAccordingToPolicy(QualType QT, const PrintingPolicy &Policy)

Definition TypePrinter.cpp:176

static bool isSubstitutedTemplateArgument(ASTContext &Ctx, TemplateArgument Arg, TemplateArgument Pattern, ArrayRef< TemplateArgument > Args, unsigned Depth)

Definition TypePrinter.cpp:2432

static void AppendTypeQualList(raw_ostream &OS, unsigned TypeQuals, bool HasRestrictKeyword)

Definition TypePrinter.cpp:149

static bool templateArgumentExpressionsEqual(ASTContext const &Ctx, TemplateArgument const &Pattern, TemplateArgument const &Arg)

Evaluates the expression template argument 'Pattern' and returns true if 'Arg' evaluates to the same ...

Definition TypePrinter.cpp:2404

C Language Family Type Representation.

Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...

SourceManager & getSourceManager()

TemplateArgument getCanonicalTemplateArgument(const TemplateArgument &Arg) const

Retrieve the "canonical" template argument.

QualType getQualifiedType(SplitQualType split) const

Un-split a SplitQualType.

static bool hasSameType(QualType T1, QualType T2)

Determine whether the given types T1 and T2 are equivalent.

QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const

Return this type as a completely-unqualified array type, capturing the qualifiers in Quals.

Represents a concrete matrix type with constant number of rows and columns.

Represents a sugar type with __counted_by or __sized_by annotations, including their _or_null variant...

ASTContext & getASTContext() const LLVM_READONLY

bool isImplicit() const

isImplicit - Indicates whether the declaration was implicitly generated by the implementation.

SourceLocation getLocation() const

void print(raw_ostream &Out, unsigned Indentation=0, bool PrintInstantiation=false) const

This represents one expression.

bool isIntegerConstantExpr(const ASTContext &Ctx) const

bool isValueDependent() const

Determines whether the value of this expression depends on.

llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const

EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.

Expr * IgnoreParenImpCasts() LLVM_READONLY

Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...

Represents a prototype with parameter type info, e.g.

ExceptionSpecificationType getExceptionSpecType() const

Get the kind of exception specification on this function.

unsigned getNumParams() const

void printExceptionSpecification(raw_ostream &OS, const PrintingPolicy &Policy) const

Definition TypePrinter.cpp:909

bool hasTrailingReturn() const

Whether this function prototype has a trailing return type.

Qualifiers getMethodQuals() const

QualType getParamType(unsigned i) const

FunctionEffectsRef getFunctionEffects() const

unsigned getAArch64SMEAttributes() const

Return a bitmask describing the SME attributes on the function type, see AArch64SMETypeAttributes for...

QualType getExceptionType(unsigned i) const

Return the ith exception type, where 0 <= i < getNumExceptions().

bool hasCFIUncheckedCallee() const

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.

CallingConv getCC() const

bool getCmseNSCall() const

bool getNoCfCheck() const

unsigned getRegParm() const

bool getNoCallerSavedRegs() const

bool getProducesResult() const

ExtInfo getExtInfo() const

@ SME_PStateSMEnabledMask

@ SME_PStateSMCompatibleMask

@ SME_AgnosticZAStateMask

static ArmStateValue getArmZT0State(unsigned AttrBits)

static ArmStateValue getArmZAState(unsigned AttrBits)

QualType getReturnType() const

StringRef getName() const

Return the actual identifier string.

Keeps track of the various options that can be enabled, which controls the dialect of C or C++ that i...

IdentifierInfo * getIdentifier() const

Get the identifier that names this declaration, if there is one.

StringRef getName() const

Get the name of identifier for this declaration as a StringRef.

void printNestedNameSpecifier(raw_ostream &OS) const

Print only the nested name specifier part of a fully-qualified name, including the '::' at the end.

Pointer-authentication qualifiers.

bool isAddressDiscriminated() const

unsigned getExtraDiscriminator() const

void print(raw_ostream &OS, const PrintingPolicy &Policy) const

Definition TypePrinter.cpp:2605

bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const

Definition TypePrinter.cpp:2601

std::string getAsString() const

Definition TypePrinter.cpp:2589

unsigned getColumn() const

Return the presumed column number of this location.

const char * getFilename() const

Return the presumed filename of this location.

unsigned getLine() const

Return the presumed line number of this location.

A (possibly-)qualified type.

bool isNull() const

Return true if this QualType doesn't point to a type yet.

Qualifiers getQualifiers() const

Retrieve the set of qualifiers applied to this type.

void print(raw_ostream &OS, const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const

Definition TypePrinter.cpp:2792

void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const

Definition TypePrinter.cpp:2807

QualType getCanonicalType() const

SplitQualType split() const

Divides a QualType into its unqualified type and a set of local qualifiers.

std::string getAsString() const

Definition TypePrinter.cpp:2775

The collection of all-type qualifiers we support.

unsigned getCVRQualifiers() const

@ OCL_Strong

Assigning into this object requires the old value to be released and the new value to be retained.

@ OCL_ExplicitNone

This object can be modified without requiring retains or releases.

@ OCL_None

There is no lifetime qualification on this type.

@ OCL_Weak

Reading or writing from this object requires a barrier call.

@ OCL_Autoreleasing

Assigning into this object requires a lifetime extension.

bool hasUnaligned() const

void print(raw_ostream &OS, const PrintingPolicy &Policy, bool appendSpaceIfNonEmpty=false) const

Definition TypePrinter.cpp:2707

bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const

Definition TypePrinter.cpp:2631

PointerAuthQualifier getPointerAuth() const

ObjCLifetime getObjCLifetime() const

std::string getAsString() const

Definition TypePrinter.cpp:2616

LangAS getAddressSpace() const

static std::string getAddrSpaceAsString(LangAS AS)

Definition TypePrinter.cpp:2652

Base for LValueReferenceType and RValueReferenceType.

PresumedLoc getPresumedLoc(SourceLocation Loc, bool UseLineDirectives=true) const

Returns the "presumed" location of a SourceLocation specifies.

StringRef getKindName() const

TypedefNameDecl * getTypedefNameForAnonDecl() const

ArrayRef< TemplateArgumentLoc > arguments() const

Location wrapper for a TemplateArgument.

const TemplateArgument & getArgument() const

TypeSourceInfo * getTypeSourceInfo() const

Represents a template argument.

ArrayRef< TemplateArgument > getPackAsArray() const

Return the array of arguments in this template argument pack.

Expr * getAsExpr() const

Retrieve the template argument as an expression.

QualType getAsType() const

Retrieve the type for a type template argument.

llvm::APSInt getAsIntegral() const

Retrieve the template argument as an integral value.

TemplateName getAsTemplate() const

Retrieve the template name for a template name argument.

unsigned pack_size() const

The number of template arguments in the given template argument pack.

bool structurallyEquals(const TemplateArgument &Other) const

Determines whether two template arguments are superficially the same.

void print(const PrintingPolicy &Policy, raw_ostream &Out, bool IncludeType) const

Print this template argument to the given output stream.

ArgKind

The kind of template argument we're storing.

@ Template

The template argument is a template name that was provided for a template template parameter.

@ Pack

The template argument is actually a parameter pack.

@ Type

The template argument is a type.

@ Integral

The template argument is an integral value stored in an llvm::APSInt that was provided for an integra...

@ Expression

The template argument is an expression, and we've not resolved it to one of the other forms yet,...

ArgKind getKind() const

Return the kind of stored template argument.

The base class of all kinds of template declarations (e.g., class, function, etc.).

TemplateParameterList * getTemplateParameters() const

Get the list of template parameters.

Represents a C++ template name within the type system.

TemplateDecl * getAsTemplateDecl(bool IgnoreDeduced=false) const

Retrieve the underlying template declaration that this template name refers to, if known.

void print(raw_ostream &OS, const PrintingPolicy &Policy, Qualified Qual=Qualified::AsWritten) const

Print the template name.

Stores a list of template parameters for a TemplateDecl and its derived classes.

ArrayRef< TemplateArgument > getInjectedTemplateArgs(const ASTContext &Context)

Get the template argument list of the template parameter list.

static bool shouldIncludeTypeForArgument(const PrintingPolicy &Policy, const TemplateParameterList *TPL, unsigned Idx)

unsigned getIndex() const

Retrieve the index of the template parameter.

const TypeConstraint * getTypeConstraint() const

Returns the type constraint associated with this template parameter (if any).

unsigned getDepth() const

Retrieve the depth of the template parameter.

QualType getType() const

Return the type wrapped by this type source info.

The base class of the type hierarchy.

QualType getLocallyUnqualifiedSingleStepDesugaredType() const

Pull a single level of sugar off of this locally-unqualified type.

const T * castAs() const

Member-template castAs.

bool isObjCQualifiedIdType() const

QualType getPointeeType() const

If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.

bool isObjCIdType() const

bool isSpecifierType() const

Returns true if this type can be represented by some set of type specifiers.

bool isFunctionType() const

bool isObjCQualifiedClassType() const

bool isObjCClassType() const

const T * getAsCanonical() const

If this type is canonically the specified type, return its canonical type cast to that specified type...

TypeClass getTypeClass() const

bool isCanonicalUnqualified() const

Determines if this type would be canonical if it had no further qualification.

const T * getAs() const

Member-template getAs'.

const internal::VariadicAllOfMatcher< Attr > attr

@ OS

Indicates that the tracking object is a descendant of a referenced-counted OSObject,...

std::variant< struct RequiresDecl, struct HeaderDecl, struct UmbrellaDirDecl, struct ModuleDecl, struct ExcludeDecl, struct ExportDecl, struct ExportAsDecl, struct ExternModuleDecl, struct UseDecl, struct LinkDecl, struct ConfigMacrosDecl, struct ConflictDecl > Decl

All declarations that can appear in a module declaration.

The JSON file list parser is used to communicate input to InstallAPI.

bool isa(CodeGen::Address addr)

llvm::StringRef getParameterABISpelling(ParameterABI kind)

Definition TypePrinter.cpp:954

bool isTargetAddressSpace(LangAS AS)

@ RQ_None

No ref-qualifier was provided.

@ RQ_LValue

An lvalue ref-qualifier was provided (&).

@ RQ_RValue

An rvalue ref-qualifier was provided (&&).

@ TemplateName

The identifier is a template name. FIXME: Add an annotation for that.

unsigned toTargetAddressSpace(LangAS AS)

ParameterABI

Kinds of parameter ABI.

@ SwiftAsyncContext

This parameter (which must have pointer type) uses the special Swift asynchronous context-pointer ABI...

@ SwiftErrorResult

This parameter (which must have pointer-to-pointer type) uses the special Swift error-result ABI trea...

@ Ordinary

This parameter uses ordinary ABI rules for its type.

@ SwiftIndirectResult

This parameter (which must have pointer type) is a Swift indirect result parameter.

@ SwiftContext

This parameter (which must have pointer type) uses the special Swift context-pointer ABI treatment.

const FunctionProtoType * T

bool isComputedNoexcept(ExceptionSpecificationType ESpecType)

@ Template

We are parsing a template declaration.

bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)

@ Keyword

The name has been typo-corrected to a keyword.

@ Type

The name was classified as a type.

LangAS

Defines the address space values used by the address space qualifier of QualType.

bool declaresSameEntity(const Decl *D1, const Decl *D2)

Determine whether two declarations declare the same entity.

llvm::StringRef getAsString(SyncScope S)

const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ConceptReference *C)

Insertion operator for diagnostics.

U cast(CodeGen::Address addr)

ElaboratedTypeKeyword

The elaboration keyword that precedes a qualified type name or introduces an elaborated-type-specifie...

@ EST_NoThrow

Microsoft __declspec(nothrow) extension.

@ EST_MSAny

Microsoft throw(...) extension.

ArrayRef< TemplateArgumentLoc > arguments() const

static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)

Describes how types, statements, expressions, and declarations should be printed.

unsigned FullyQualifiedName

When true, print the fully qualified name of function declarations.

unsigned MSVCFormatting

Use whitespace and punctuation like MSVC does.

unsigned SuppressDefaultTemplateArgs

When true, attempt to suppress template arguments that match the default argument for the parameter.

unsigned SplitTemplateClosers

Whether nested templates must be closed like 'a<b >' rather than 'a<b>'.

unsigned PrintInjectedClassNameWithArguments

Whether to print an InjectedClassNameType with template arguments or as written.

unsigned UseVoidForZeroParams

Whether we should use '(void)' rather than '()' for a function prototype with zero parameters.

unsigned AnonymousTagLocations

When printing an anonymous tag name, also print the location of that entity (e.g.,...

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 UsePreferredNames

Whether to use C++ template preferred_name attributes when printing templates.

unsigned SuppressStrongLifetime

When true, suppress printing of the __strong lifetime qualifier in ARC.

unsigned Restrict

Whether we can use 'restrict' rather than '__restrict'.

unsigned UseHLSLTypes

Whether or not we're printing known HLSL code and should print HLSL sugared types when possible.

unsigned SuppressScope

Suppresses printing of scope specifiers.

const PrintingCallbacks * Callbacks

Callbacks to use to allow the behavior of printing to be customized.

unsigned IncludeTagDefinition

When true, include the body of a tag definition.

unsigned PrintAsCanonical

Whether to print entities as written or canonically.

A std::pair-like structure for storing a qualified type split into its local qualifiers and its local...

const Type * Ty

The locally-unqualified type.

Qualifiers Quals

The local qualifiers.