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 {

55 bool Old;

56

57public:

58 explicit IncludeStrongLifetimeRAII(PrintingPolicy &Policy)

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

62 }

63

65};

66

67class ParamPolicyRAII {

69 bool Old;

70

71public:

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

75 }

76

78};

79

80class DefaultTemplateArgsPolicyRAII {

82 bool Old;

83

84public:

85 explicit DefaultTemplateArgsPolicyRAII(PrintingPolicy &Policy)

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

88 }

89

91};

92

93class ElaboratedTypePolicyRAII {

95 bool SuppressTagKeyword;

96 bool SuppressScope;

97

98public:

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

104 }

105

106 ~ElaboratedTypePolicyRAII() {

109 }

110};

111

112class TypePrinter {

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

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);

130 bool FullyQualify);

131

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

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

134 void AppendScope(DeclContext *DC, raw_ostream &OS,

136 void printTag(TagDecl *T, raw_ostream &OS);

138#define ABSTRACT_TYPE(CLASS, PARENT)

139#define TYPE(CLASS, PARENT) \

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

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

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

143

144private:

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

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

147};

148

149}

150

152 bool HasRestrictKeyword) {

153 bool appendSpace = false;

155 OS << "const";

156 appendSpace = true;

157 }

159 if (appendSpace) OS << ' ';

160 OS << "volatile";

161 appendSpace = true;

162 }

164 if (appendSpace) OS << ' ';

165 if (HasRestrictKeyword) {

166 OS << "restrict";

167 } else {

168 OS << "__restrict";

169 }

170 }

171}

172

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

174 if (!HasEmptyPlaceHolder)

175 OS << ' ';

176}

177

182 return QT.split();

183}

184

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

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

188}

189

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

191 StringRef PlaceHolder) {

192 if (T) {

193 OS << "NULL TYPE";

194 return;

195 }

196

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

198

199 printBefore(T, Quals, OS);

200 OS << PlaceHolder;

201 printAfter(T, Quals, OS);

202}

203

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

205 bool &NeedARCStrongQualifier) {

206

207

208

209

210

211 bool CanPrefixQualifiers = false;

212 NeedARCStrongQualifier = false;

213 const Type *UnderlyingType = T;

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

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

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

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

219

220 switch (TC) {

221 case Type::Auto:

222 case Type::Builtin:

223 case Type::Complex:

224 case Type::UnresolvedUsing:

225 case Type::Using:

226 case Type::Typedef:

227 case Type::TypeOfExpr:

228 case Type::TypeOf:

229 case Type::Decltype:

230 case Type::UnaryTransform:

231 case Type::Record:

232 case Type::Enum:

233 case Type::Elaborated:

234 case Type::TemplateTypeParm:

235 case Type::SubstTemplateTypeParmPack:

236 case Type::DeducedTemplateSpecialization:

237 case Type::TemplateSpecialization:

238 case Type::InjectedClassName:

239 case Type::DependentName:

240 case Type::DependentTemplateSpecialization:

241 case Type::ObjCObject:

242 case Type::ObjCTypeParam:

243 case Type::ObjCInterface:

244 case Type::Atomic:

245 case Type::Pipe:

246 case Type::BitInt:

247 case Type::DependentBitInt:

248 case Type::BTFTagAttributed:

249 case Type::HLSLAttributedResource:

250 CanPrefixQualifiers = true;

251 break;

252

253 case Type::ObjCObjectPointer:

256 break;

257

258 case Type::VariableArray:

259 case Type::DependentSizedArray:

260 NeedARCStrongQualifier = true;

261 [[fallthrough]];

262

263 case Type::ConstantArray:

264 case Type::IncompleteArray:

265 return canPrefixQualifiers(

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

267 NeedARCStrongQualifier);

268

269 case Type::Adjusted:

270 case Type::Decayed:

271 case Type::ArrayParameter:

272 case Type::Pointer:

273 case Type::BlockPointer:

274 case Type::LValueReference:

275 case Type::RValueReference:

276 case Type::MemberPointer:

277 case Type::DependentAddressSpace:

278 case Type::DependentVector:

279 case Type::DependentSizedExtVector:

280 case Type::Vector:

281 case Type::ExtVector:

282 case Type::ConstantMatrix:

283 case Type::DependentSizedMatrix:

284 case Type::FunctionProto:

285 case Type::FunctionNoProto:

286 case Type::Paren:

287 case Type::PackExpansion:

288 case Type::SubstTemplateTypeParm:

289 case Type::MacroQualified:

290 case Type::CountAttributed:

291 CanPrefixQualifiers = false;

292 break;

293

294 case Type::Attributed: {

295

296

297 const auto *AttrTy = cast(UnderlyingType);

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

299 break;

300 }

301 case Type::PackIndexing: {

302 return canPrefixQualifiers(

303 cast(UnderlyingType)->getPattern().getTypePtr(),

304 NeedARCStrongQualifier);

305 }

306 }

307

308 return CanPrefixQualifiers;

309}

310

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

313

314

315

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

319

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

321}

322

323

324

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

327 return;

328

330

331

332

333 bool CanPrefixQualifiers = false;

334 bool NeedARCStrongQualifier = false;

335 CanPrefixQualifiers = canPrefixQualifiers(T, NeedARCStrongQualifier);

336

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

338 if (NeedARCStrongQualifier) {

339 IncludeStrongLifetimeRAII Strong(Policy);

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

341 } else {

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

343 }

344 }

345

346 bool hasAfterQuals = false;

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

349 if (hasAfterQuals)

350 HasEmptyPlaceHolder = false;

351 }

352

354#define ABSTRACT_TYPE(CLASS, PARENT)

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

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

357 break;

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

359 }

360

361 if (hasAfterQuals) {

362 if (NeedARCStrongQualifier) {

363 IncludeStrongLifetimeRAII Strong(Policy);

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

365 } else {

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

367 }

368 }

369}

370

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

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

374}

375

376

377

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

380#define ABSTRACT_TYPE(CLASS, PARENT)

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

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

383 break;

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

385 }

386}

387

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

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

390 spaceBeforePlaceHolder(OS);

391}

392

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

394

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

396 OS << "_Complex ";

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

398}

399

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

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

402}

403

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

405 IncludeStrongLifetimeRAII Strong(Policy);

406 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

408

409

411 OS << '(';

412 OS << '*';

413}

414

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

416 IncludeStrongLifetimeRAII Strong(Policy);

417 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

418

419

421 OS << ')';

423}

424

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

426 raw_ostream &OS) {

427 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

429 OS << '^';

430}

431

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

433 raw_ostream &OS) {

434 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

436}

437

438

439

443 return T;

444}

445

447 raw_ostream &OS) {

448 IncludeStrongLifetimeRAII Strong(Policy);

449 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

451 printBefore(Inner, OS);

452

453

454 if (isa(Inner))

455 OS << '(';

456 OS << '&';

457}

458

460 raw_ostream &OS) {

461 IncludeStrongLifetimeRAII Strong(Policy);

462 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

464

465

466 if (isa(Inner))

467 OS << ')';

468 printAfter(Inner, OS);

469}

470

472 raw_ostream &OS) {

473 IncludeStrongLifetimeRAII Strong(Policy);

474 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

476 printBefore(Inner, OS);

477

478

479 if (isa(Inner))

480 OS << '(';

481 OS << "&&";

482}

483

485 raw_ostream &OS) {

486 IncludeStrongLifetimeRAII Strong(Policy);

487 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

489

490

491 if (isa(Inner))

492 OS << ')';

493 printAfter(Inner, OS);

494}

495

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

497 raw_ostream &OS) {

498 IncludeStrongLifetimeRAII Strong(Policy);

499 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

501

502

504 OS << '(';

505

507 InnerPolicy.IncludeTagDefinition = false;

508 TypePrinter(InnerPolicy).print(QualType(T->getClass(), 0), OS, StringRef());

509

510 OS << "::*";

511}

512

514 raw_ostream &OS) {

515 IncludeStrongLifetimeRAII Strong(Policy);

516 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

517

518

520 OS << ')';

522}

523

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

525 raw_ostream &OS) {

526 IncludeStrongLifetimeRAII Strong(Policy);

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

528}

529

531 raw_ostream &OS) {

532 OS << '[';

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

535 Policy.Restrict);

536 OS << ' ';

537 }

538

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

540 OS << "static ";

541

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

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

544}

545

547 raw_ostream &OS) {

548 IncludeStrongLifetimeRAII Strong(Policy);

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

550}

551

553 raw_ostream &OS) {

554 OS << "[]";

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

556}

557

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

559 raw_ostream &OS) {

560 IncludeStrongLifetimeRAII Strong(Policy);

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

562}

563

565 raw_ostream &OS) {

566 OS << '[';

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

569 OS << ' ';

570 }

571

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

573 OS << "static ";

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

575 OS << '*';

576

577 if (T->getSizeExpr())

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

579 OS << ']';

580

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

582}

583

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

585

586

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

588}

589

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

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

592}

593

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

595

596 printAdjustedBefore(T, OS);

597}

598

600 raw_ostream &OS) {

601 printConstantArrayAfter(T, OS);

602}

603

605 raw_ostream &OS) {

606 printConstantArrayBefore(T, OS);

607}

608

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

610 printAdjustedAfter(T, OS);

611}

612

613void TypePrinter::printDependentSizedArrayBefore(

615 raw_ostream &OS) {

616 IncludeStrongLifetimeRAII Strong(Policy);

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

618}

619

620void TypePrinter::printDependentSizedArrayAfter(

622 raw_ostream &OS) {

623 OS << '[';

624 if (T->getSizeExpr())

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

626 OS << ']';

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

628}

629

630void TypePrinter::printDependentAddressSpaceBefore(

633}

634

635void TypePrinter::printDependentAddressSpaceAfter(

637 OS << " __attribute__((address_space(";

638 if (T->getAddrSpaceExpr())

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

640 OS << ")))";

642}

643

644void TypePrinter::printDependentSizedExtVectorBefore(

646 raw_ostream &OS) {

647 if (Policy.UseHLSLTypes)

648 OS << "vector<";

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

650}

651

652void TypePrinter::printDependentSizedExtVectorAfter(

654 raw_ostream &OS) {

655 if (Policy.UseHLSLTypes) {

656 OS << ", ";

657 if (T->getSizeExpr())

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

659 OS << ">";

660 } else {

661 OS << " __attribute__((ext_vector_type(";

662 if (T->getSizeExpr())

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

664 OS << ")))";

665 }

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

667}

668

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

670 switch (T->getVectorKind()) {

671 case VectorKind::AltiVecPixel:

672 OS << "__vector __pixel ";

673 break;

674 case VectorKind::AltiVecBool:

675 OS << "__vector __bool ";

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

677 break;

678 case VectorKind::AltiVecVector:

679 OS << "__vector ";

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

681 break;

682 case VectorKind::Neon:

683 OS << "__attribute__((neon_vector_type("

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

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

686 break;

687 case VectorKind::NeonPoly:

688 OS << "__attribute__((neon_polyvector_type(" <<

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

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

691 break;

692 case VectorKind::Generic: {

693

694

695 OS << "__attribute__((__vector_size__("

696 << T->getNumElements()

697 << " * sizeof(";

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

699 OS << ")))) ";

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

701 break;

702 }

703 case VectorKind::SveFixedLengthData:

704 case VectorKind::SveFixedLengthPredicate:

705

706

707 OS << "__attribute__((__arm_sve_vector_bits__(";

708

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

710

711

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

713 else

714 OS << T->getNumElements();

715

716 OS << " * sizeof(";

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

718

719 OS << ") * 8))) ";

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

721 break;

722 case VectorKind::RVVFixedLengthData:

723 case VectorKind::RVVFixedLengthMask:

724 case VectorKind::RVVFixedLengthMask_1:

725 case VectorKind::RVVFixedLengthMask_2:

726 case VectorKind::RVVFixedLengthMask_4:

727

728

729 OS << "__attribute__((__riscv_rvv_vector_bits__(";

730

731 OS << T->getNumElements();

732

733 OS << " * sizeof(";

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

735

736 OS << ") * 8))) ";

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

738 break;

739 }

740}

741

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

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

744}

745

746void TypePrinter::printDependentVectorBefore(

748 switch (T->getVectorKind()) {

749 case VectorKind::AltiVecPixel:

750 OS << "__vector __pixel ";

751 break;

752 case VectorKind::AltiVecBool:

753 OS << "__vector __bool ";

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

755 break;

756 case VectorKind::AltiVecVector:

757 OS << "__vector ";

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

759 break;

760 case VectorKind::Neon:

761 OS << "__attribute__((neon_vector_type(";

762 if (T->getSizeExpr())

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

764 OS << "))) ";

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

766 break;

767 case VectorKind::NeonPoly:

768 OS << "__attribute__((neon_polyvector_type(";

769 if (T->getSizeExpr())

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

771 OS << "))) ";

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

773 break;

774 case VectorKind::Generic: {

775

776

777 OS << "__attribute__((__vector_size__(";

778 if (T->getSizeExpr())

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

780 OS << " * sizeof(";

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

782 OS << ")))) ";

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

784 break;

785 }

786 case VectorKind::SveFixedLengthData:

787 case VectorKind::SveFixedLengthPredicate:

788

789

790 OS << "__attribute__((__arm_sve_vector_bits__(";

791 if (T->getSizeExpr()) {

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

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

794

795

796 OS << " * 8";

797 OS << " * sizeof(";

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

799

800 OS << ") * 8";

801 }

802 OS << "))) ";

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

804 break;

805 case VectorKind::RVVFixedLengthData:

806 case VectorKind::RVVFixedLengthMask:

807 case VectorKind::RVVFixedLengthMask_1:

808 case VectorKind::RVVFixedLengthMask_2:

809 case VectorKind::RVVFixedLengthMask_4:

810

811

812 OS << "__attribute__((__riscv_rvv_vector_bits__(";

813 if (T->getSizeExpr()) {

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

815 OS << " * sizeof(";

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

817

818 OS << ") * 8";

819 }

820 OS << "))) ";

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

822 break;

823 }

824}

825

826void TypePrinter::printDependentVectorAfter(

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

829}

830

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

832 raw_ostream &OS) {

833 if (Policy.UseHLSLTypes)

834 OS << "vector<";

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

836}

837

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

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

840

841 if (Policy.UseHLSLTypes) {

842 OS << ", ";

843 OS << T->getNumElements();

844 OS << ">";

845 } else {

846 OS << " __attribute__((ext_vector_type(";

847 OS << T->getNumElements();

848 OS << ")))";

849 }

850}

851

853 raw_ostream &OS) {

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

855 OS << " __attribute__((matrix_type(";

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

857 OS << ")))";

858}

859

861 raw_ostream &OS) {

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

863}

864

865void TypePrinter::printDependentSizedMatrixBefore(

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

868 OS << " __attribute__((matrix_type(";

869 if (T->getRowExpr()) {

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

871 }

872 OS << ", ";

873 if (T->getColumnExpr()) {

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

875 }

876 OS << ")))";

877}

878

879void TypePrinter::printDependentSizedMatrixAfter(

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

882}

883

884void

887 const {

889 OS << " throw(";

891 OS << "...";

892 else

894 if (I)

895 OS << ", ";

896

898 }

899 OS << ')';

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

903 OS << " noexcept";

904

905

907 OS << '(';

910 OS << ')';

911 }

912 }

913}

914

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

916 raw_ostream &OS) {

918 OS << "auto ";

919 if (!HasEmptyPlaceHolder)

920 OS << '(';

921 } else {

922

923 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);

925 if (!PrevPHIsEmpty.get())

926 OS << '(';

927 }

928}

929

931 switch (ABI) {

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

935 return "swift_context";

937 return "swift_async_context";

939 return "swift_error_result";

941 return "swift_indirect_result";

943 return "out";

945 return "inout";

946 }

947 llvm_unreachable("bad parameter ABI kind");

948}

949

951 raw_ostream &OS) {

952

953 if (!HasEmptyPlaceHolder)

954 OS << ')';

955 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

956

957 OS << '(';

958 {

959 ParamPolicyRAII ParamPolicy(Policy);

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

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

962

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

965 if (EPI.isNoEscape())

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

967 auto ABI = EPI.getABI();

970 if (Policy.UseHLSLTypes) {

971

972

973

974

976 continue;

977 }

980

982 }

983 }

984

987 OS << ", ";

988 OS << "...";

989 } else if (T->getNumParams() == 0 && Policy.UseVoidForZeroParams) {

990

991 OS << "void";

992 }

993

994 OS << ')';

995

998

1000 OS << " __arm_streaming_compatible";

1002 OS << " __arm_streaming";

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

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

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

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

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

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

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

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

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

1021

1022 printFunctionAfter(Info, OS);

1023

1026

1029 break;

1030

1032 OS << " &";

1033 break;

1034

1036 OS << " &&";

1037 break;

1038 }

1040

1042 for (const auto &CFE : FX) {

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

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

1045 OS << '(';

1047 OS << ')';

1048 }

1049 OS << "))";

1050 }

1051

1053 OS << " -> ";

1055 } else

1057}

1058

1060 raw_ostream &OS) {

1061 if (!InsideCCAttribute) {

1062 switch (Info.getCC()) {

1064

1065

1066

1067

1068

1069

1070

1071 break;

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

1074 break;

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

1077 break;

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

1080 break;

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

1083 break;

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

1086 break;

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

1089 break;

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

1092 break;

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

1095 break;

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

1098 break;

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

1101 break;

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

1104 break;

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

1107 break;

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

1110 break;

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

1113 break;

1116

1117 break;

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

1120 break;

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

1123 break;

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

1126 break;

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

1129 break;

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

1132 break;

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

1135 break;

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

1138 break;

1139 }

1140 }

1141

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

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

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

1149 OS << " __attribute__((regparm ("

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

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

1155}

1156

1158 raw_ostream &OS) {

1159

1160 SaveAndRestore PrevPHIsEmpty(HasEmptyPlaceHolder, false);

1162 if (!PrevPHIsEmpty.get())

1163 OS << '(';

1164}

1165

1167 raw_ostream &OS) {

1168

1169 if (!HasEmptyPlaceHolder)

1170 OS << ')';

1171 SaveAndRestore NonEmptyPH(HasEmptyPlaceHolder, false);

1172

1173 OS << "()";

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

1176}

1177

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

1179

1180

1181

1182

1183 if (!Policy.SuppressScope)

1185

1188 spaceBeforePlaceHolder(OS);

1189}

1190

1192 raw_ostream &OS) {

1193 printTypeSpec(T->getDecl(), OS);

1194}

1195

1197 raw_ostream &OS) {}

1198

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

1200

1201

1202

1203

1204

1205

1206

1207

1208

1209 printTypeSpec(T->getFoundDecl()->getUnderlyingDecl(), OS);

1210}

1211

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

1213

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

1215 printTypeSpec(T->getDecl(), OS);

1216}

1217

1219 raw_ostream &OS) {

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

1221 OS << MacroName << " ";

1222

1223

1224

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

1226}

1227

1229 raw_ostream &OS) {

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

1231}

1232

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

1234

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

1236 raw_ostream &OS) {

1238 : "typeof ");

1239 if (T->getUnderlyingExpr())

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

1241 spaceBeforePlaceHolder(OS);

1242}

1243

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

1245 raw_ostream &OS) {}

1246

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

1249 : "typeof(");

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

1251 OS << ')';

1252 spaceBeforePlaceHolder(OS);

1253}

1254

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

1256

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

1258 OS << "decltype(";

1259 if (T->getUnderlyingExpr())

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

1261 OS << ')';

1262 spaceBeforePlaceHolder(OS);

1263}

1264

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

1266 raw_ostream &OS) {

1267 if (T->hasSelectedType()) {

1268 OS << T->getSelectedType();

1269 } else {

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

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

1272 OS << "]";

1273 }

1274 spaceBeforePlaceHolder(OS);

1275}

1276

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

1278 raw_ostream &OS) {}

1279

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

1281

1283 raw_ostream &OS) {

1284 IncludeStrongLifetimeRAII Strong(Policy);

1285

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

1287#define TRANSFORM_TYPE_TRAIT_DEF(Enum, Trait) \

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

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

1290 }};

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

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

1293 OS << ')';

1294 spaceBeforePlaceHolder(OS);

1295}

1296

1298 raw_ostream &OS) {}

1299

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

1301

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

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

1304 } else {

1305 if (T->isConstrained()) {

1306

1307

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

1309 auto Args = T->getTypeConstraintArguments();

1310 if (!Args.empty())

1312 OS, Args, Policy,

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

1314 OS << ' ';

1315 }

1316 switch (T->getKeyword()) {

1320 }

1321 spaceBeforePlaceHolder(OS);

1322 }

1323}

1324

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

1326

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

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

1329}

1330

1331void TypePrinter::printDeducedTemplateSpecializationBefore(

1333

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

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

1336 } else {

1337 IncludeStrongLifetimeRAII Strong(Policy);

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

1339 spaceBeforePlaceHolder(OS);

1340 }

1341}

1342

1343void TypePrinter::printDeducedTemplateSpecializationAfter(

1345

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

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

1348}

1349

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

1351 IncludeStrongLifetimeRAII Strong(Policy);

1352

1353 OS << "_Atomic(";

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

1355 OS << ')';

1356 spaceBeforePlaceHolder(OS);

1357}

1358

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

1360

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

1362 IncludeStrongLifetimeRAII Strong(Policy);

1363

1364 if (T->isReadOnly())

1365 OS << "read_only ";

1366 else

1367 OS << "write_only ";

1368 OS << "pipe ";

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

1370 spaceBeforePlaceHolder(OS);

1371}

1372

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

1374

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

1376 if (T->isUnsigned())

1377 OS << "unsigned ";

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

1379 spaceBeforePlaceHolder(OS);

1380}

1381

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

1383

1385 raw_ostream &OS) {

1386 if (T->isUnsigned())

1387 OS << "unsigned ";

1388 OS << "_BitInt(";

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

1390 OS << ")";

1391 spaceBeforePlaceHolder(OS);

1392}

1393

1395 raw_ostream &OS) {}

1396

1397

1398void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS,

1401 return;

1402

1403

1404

1406 return;

1407

1408 if (Policy.Callbacks && Policy.Callbacks->isScopeVisible(DC))

1409 return;

1410

1411 if (const auto *NS = dyn_cast(DC)) {

1412 if (Policy.SuppressUnwrittenScope && NS->isAnonymousNamespace())

1413 return AppendScope(DC->getParent(), OS, NameInScope);

1414

1415

1416

1417 if (Policy.SuppressInlineNamespace !=

1419 NS->isInline() && NameInScope &&

1420 NS->isRedundantInlineQualifierFor(NameInScope))

1421 return AppendScope(DC->getParent(), OS, NameInScope);

1422

1423 AppendScope(DC->getParent(), OS, NS->getDeclName());

1424 if (NS->getIdentifier())

1425 OS << NS->getName() << "::";

1426 else

1427 OS << "(anonymous namespace)::";

1428 } else if (const auto *Spec = dyn_cast(DC)) {

1429 AppendScope(DC->getParent(), OS, Spec->getDeclName());

1430 IncludeStrongLifetimeRAII Strong(Policy);

1431 OS << Spec->getIdentifier()->getName();

1434 OS, TemplateArgs.asArray(), Policy,

1435 Spec->getSpecializedTemplate()->getTemplateParameters());

1436 OS << "::";

1437 } else if (const auto *Tag = dyn_cast(DC)) {

1438 AppendScope(DC->getParent(), OS, Tag->getDeclName());

1440 OS << Typedef->getIdentifier()->getName() << "::";

1441 else if (Tag->getIdentifier())

1442 OS << Tag->getIdentifier()->getName() << "::";

1443 else

1444 return;

1445 } else {

1446 AppendScope(DC->getParent(), OS, NameInScope);

1447 }

1448}

1449

1450void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {

1451 if (Policy.IncludeTagDefinition) {

1454 D->print(OS, SubPolicy, Indentation);

1455 spaceBeforePlaceHolder(OS);

1456 return;

1457 }

1458

1459 bool HasKindDecoration = false;

1460

1461

1462

1463 if (!Policy.SuppressTagKeyword && D->getTypedefNameForAnonDecl()) {

1464 HasKindDecoration = true;

1465 OS << D->getKindName();

1466 OS << ' ';

1467 }

1468

1469

1470

1471

1472 if (!Policy.SuppressScope)

1474

1477 else if (TypedefNameDecl *Typedef = D->getTypedefNameForAnonDecl()) {

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

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

1480 } else {

1481

1482

1483 OS << (Policy.MSVCFormatting ? '`' : '(');

1484

1485 if (isa(D) && cast(D)->isLambda()) {

1486 OS << "lambda";

1487 HasKindDecoration = true;

1488 } else if ((isa(D) && cast(D)->isAnonymousStructOrUnion())) {

1489 OS << "anonymous";

1490 } else {

1491 OS << "unnamed";

1492 }

1493

1494 if (Policy.AnonymousTagLocations) {

1495

1496

1497

1498 if (!HasKindDecoration)

1499 OS << " " << D->getKindName();

1500

1504 OS << " at ";

1507 if (auto *Callbacks = Policy.Callbacks)

1508 WrittenFile = Callbacks->remapPath(File);

1509

1510

1511

1512 llvm::sys::path::Style Style =

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

1514 ? llvm::sys::path::Style::native

1515 : (Policy.MSVCFormatting

1516 ? llvm::sys::path::Style::windows_backslash

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

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

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

1520 }

1521 }

1522

1523 OS << (Policy.MSVCFormatting ? '\'' : ')');

1524 }

1525

1526

1527

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

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

1532 S->getTemplateArgsAsWritten();

1533 IncludeStrongLifetimeRAII Strong(Policy);

1534 if (TArgAsWritten && !Policy.PrintCanonicalTypes)

1536 TParams);

1537 else

1539 TParams);

1540 }

1541

1542 spaceBeforePlaceHolder(OS);

1543}

1544

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

1546

1547 if (Policy.UsePreferredNames) {

1548 for (const auto *PNA : T->getDecl()->specific_attrs()) {

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

1550 T->getDecl()))

1551 continue;

1552

1553 QualType T = PNA->getTypedefType();

1554 while (true) {

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

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

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

1558 return printTemplateId(TST, OS, true);

1560 }

1561 }

1562 }

1563

1564 printTag(T->getDecl(), OS);

1565}

1566

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

1568

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

1570 printTag(T->getDecl(), OS);

1571}

1572

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

1574

1576 raw_ostream &OS) {

1579 if (auto *TC = D->getTypeConstraint()) {

1580 TC->print(OS, Policy);

1581 OS << ' ';

1582 }

1583 OS << "auto";

1585 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()

1586 : Id->getName());

1587 else

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

1589

1590 spaceBeforePlaceHolder(OS);

1591}

1592

1594 raw_ostream &OS) {}

1595

1596void TypePrinter::printSubstTemplateTypeParmBefore(

1598 raw_ostream &OS) {

1599 IncludeStrongLifetimeRAII Strong(Policy);

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

1601}

1602

1603void TypePrinter::printSubstTemplateTypeParmAfter(

1605 raw_ostream &OS) {

1606 IncludeStrongLifetimeRAII Strong(Policy);

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

1608}

1609

1610void TypePrinter::printSubstTemplateTypeParmPackBefore(

1612 raw_ostream &OS) {

1613 IncludeStrongLifetimeRAII Strong(Policy);

1616 if (auto *TC = D->getTypeConstraint()) {

1617 TC->print(OS, Policy);

1618 OS << ' ';

1619 }

1620 OS << "auto";

1622 OS << (Policy.CleanUglifiedParameters ? Id->deuglifiedName()

1623 : Id->getName());

1624 else

1625 OS << "type-parameter-" << D->getDepth() << '-' << D->getIndex();

1626

1627 spaceBeforePlaceHolder(OS);

1628 }

1629}

1630

1631void TypePrinter::printSubstTemplateTypeParmPackAfter(

1633 raw_ostream &OS) {

1634 IncludeStrongLifetimeRAII Strong(Policy);

1635}

1636

1638 raw_ostream &OS, bool FullyQualify) {

1639 IncludeStrongLifetimeRAII Strong(Policy);

1640

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

1643

1644 if (FullyQualify && TD) {

1645 if (!Policy.SuppressScope)

1647

1649 } else {

1651 }

1652

1653 DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);

1656 spaceBeforePlaceHolder(OS);

1657}

1658

1659void TypePrinter::printTemplateSpecializationBefore(

1661 raw_ostream &OS) {

1662 printTemplateId(T, OS, Policy.FullyQualifiedName);

1663}

1664

1665void TypePrinter::printTemplateSpecializationAfter(

1667 raw_ostream &OS) {}

1668

1670 raw_ostream &OS) {

1671 if (Policy.PrintInjectedClassNameWithArguments)

1672 return printTemplateSpecializationBefore(T->getInjectedTST(), OS);

1673

1674 IncludeStrongLifetimeRAII Strong(Policy);

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

1676 spaceBeforePlaceHolder(OS);

1677}

1678

1680 raw_ostream &OS) {}

1681

1682void TypePrinter::printElaboratedBefore(const ElaboratedType *T,

1683 raw_ostream &OS) {

1684 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl()) {

1685 TagDecl *OwnedTagDecl = T->getOwnedTagDecl();

1686 assert(OwnedTagDecl->getTypeForDecl() == T->getNamedType().getTypePtr() &&

1687 "OwnedTagDecl expected to be a declaration for the type");

1690 OwnedTagDecl->print(OS, SubPolicy, Indentation);

1691 spaceBeforePlaceHolder(OS);

1692 return;

1693 }

1694

1695 if (Policy.SuppressElaboration) {

1696 printBefore(T->getNamedType(), OS);

1697 return;

1698 }

1699

1700

1701 if (!Policy.IncludeTagDefinition)

1702 {

1705 OS << " ";

1707 if (!Policy.SuppressTagKeyword && Policy.SuppressScope &&

1708 !Policy.SuppressUnwrittenScope) {

1709 bool OldTagKeyword = Policy.SuppressTagKeyword;

1710 bool OldSupressScope = Policy.SuppressScope;

1711 Policy.SuppressTagKeyword = true;

1712 Policy.SuppressScope = false;

1713 printBefore(T->getNamedType(), OS);

1714 Policy.SuppressTagKeyword = OldTagKeyword;

1715 Policy.SuppressScope = OldSupressScope;

1716 return;

1717 }

1718 if (Qualifier)

1720 }

1721

1722 ElaboratedTypePolicyRAII PolicyRAII(Policy);

1723 printBefore(T->getNamedType(), OS);

1724}

1725

1726void TypePrinter::printElaboratedAfter(const ElaboratedType *T,

1727 raw_ostream &OS) {

1728 if (Policy.IncludeTagDefinition && T->getOwnedTagDecl())

1729 return;

1730

1731 if (Policy.SuppressElaboration) {

1732 printAfter(T->getNamedType(), OS);

1733 return;

1734 }

1735

1736 ElaboratedTypePolicyRAII PolicyRAII(Policy);

1737 printAfter(T->getNamedType(), OS);

1738}

1739

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

1741 if (!HasEmptyPlaceHolder && !isa(T->getInnerType())) {

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

1743 OS << '(';

1744 } else

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

1746}

1747

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

1749 if (!HasEmptyPlaceHolder && !isa(T->getInnerType())) {

1750 OS << ')';

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

1752 } else

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

1754}

1755

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

1757 raw_ostream &OS) {

1760 OS << " ";

1761

1762 T->getQualifier()->print(OS, Policy);

1763

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

1765 spaceBeforePlaceHolder(OS);

1766}

1767

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

1769 raw_ostream &OS) {}

1770

1771void TypePrinter::printDependentTemplateSpecializationBefore(

1773 IncludeStrongLifetimeRAII Strong(Policy);

1774

1777 OS << " ";

1778

1779 if (T->getQualifier())

1780 T->getQualifier()->print(OS, Policy);

1781 OS << "template " << T->getIdentifier()->getName();

1783 spaceBeforePlaceHolder(OS);

1784}

1785

1786void TypePrinter::printDependentTemplateSpecializationAfter(

1788

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

1790 raw_ostream &OS) {

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

1792}

1793

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

1795 raw_ostream &OS) {

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

1797 OS << "...";

1798}

1799

1801 raw_ostream &OS,

1803 OS << ' ';

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

1805 OS << "__sized_by_or_null(";

1806 else if (T->isCountInBytes())

1807 OS << "__sized_by(";

1808 else if (T->isOrNull())

1809 OS << "__counted_by_or_null(";

1810 else

1811 OS << "__counted_by(";

1812 if (T->getCountExpr())

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

1814 OS << ')';

1815}

1816

1818 raw_ostream &OS) {

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

1822}

1823

1825 raw_ostream &OS) {

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

1829}

1830

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

1832 raw_ostream &OS) {

1833

1834

1835

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

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

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

1839

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

1841 OS << "__kindof ";

1842

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

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

1845 else

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

1847

1848 if (T->isMSTypeSpec()) {

1849 switch (T->getAttrKind()) {

1850 default: return;

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

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

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

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

1855 }

1856 spaceBeforePlaceHolder(OS);

1857 }

1858

1859 if (T->isWebAssemblyFuncrefSpec())

1860 OS << "__funcref";

1861

1862

1863 if (T->getImmediateNullability()) {

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

1865 OS << " _Nonnull";

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

1867 OS << " _Nullable";

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

1869 OS << " _Null_unspecified";

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

1871 OS << " _Nullable_result";

1872 else

1873 llvm_unreachable("unhandled nullability");

1874 spaceBeforePlaceHolder(OS);

1875 }

1876}

1877

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

1879 raw_ostream &OS) {

1880

1881

1882

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

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

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

1886

1887

1888

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

1890

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

1892

1893

1894

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

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

1897 return;

1898

1899

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

1901 return;

1902

1903

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

1907 return;

1908

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

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

1911 return;

1912 }

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

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

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

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

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

1918 OS << ")]]";

1919 return;

1920 }

1921

1922

1923

1924

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

1926 return;

1927

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

1929

1930

1931

1932

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

1934 return;

1935 }

1936

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

1938 OS << "__arm_streaming";

1939 return;

1940 }

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

1942 OS << "__arm_streaming_compatible";

1943 return;

1944 }

1945

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

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

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

1949 << "\")))";

1950 }

1951 return;

1952 }

1953

1954 OS << " __attribute__((";

1955 switch (T->getAttrKind()) {

1956#define TYPE_ATTR(NAME)

1957#define DECL_OR_TYPE_ATTR(NAME)

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

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

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

1961

1962 case attr::BTFTypeTag:

1963 llvm_unreachable("BTFTypeTag attribute handled separately");

1964

1965 case attr::HLSLResourceClass:

1966 case attr::HLSLROV:

1967 case attr::HLSLRawBuffer:

1968 case attr::HLSLContainedType:

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

1970

1971 case attr::OpenCLPrivateAddressSpace:

1972 case attr::OpenCLGlobalAddressSpace:

1973 case attr::OpenCLGlobalDeviceAddressSpace:

1974 case attr::OpenCLGlobalHostAddressSpace:

1975 case attr::OpenCLLocalAddressSpace:

1976 case attr::OpenCLConstantAddressSpace:

1977 case attr::OpenCLGenericAddressSpace:

1978 case attr::HLSLGroupSharedAddressSpace:

1979

1980

1981 break;

1982

1983 case attr::CountedBy:

1984 case attr::CountedByOrNull:

1985 case attr::SizedBy:

1986 case attr::SizedByOrNull:

1987 case attr::LifetimeBound:

1988 case attr::LifetimeCaptureBy:

1989 case attr::TypeNonNull:

1990 case attr::TypeNullable:

1991 case attr::TypeNullableResult:

1992 case attr::TypeNullUnspecified:

1993 case attr::ObjCGC:

1994 case attr::ObjCInertUnsafeUnretained:

1995 case attr::ObjCKindOf:

1996 case attr::ObjCOwnership:

1997 case attr::Ptr32:

1998 case attr::Ptr64:

1999 case attr::SPtr:

2000 case attr::UPtr:

2001 case attr::AddressSpace:

2002 case attr::CmseNSCall:

2003 case attr::AnnotateType:

2004 case attr::WebAssemblyFuncref:

2005 case attr::ArmAgnostic:

2006 case attr::ArmStreaming:

2007 case attr::ArmStreamingCompatible:

2008 case attr::ArmIn:

2009 case attr::ArmOut:

2010 case attr::ArmInOut:

2011 case attr::ArmPreserves:

2012 case attr::NonBlocking:

2013 case attr::NonAllocating:

2014 case attr::Blocking:

2015 case attr::Allocating:

2016 case attr::SwiftAttr:

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

2018

2019 case attr::NSReturnsRetained:

2020 OS << "ns_returns_retained";

2021 break;

2022

2023

2024

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

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

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

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

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

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

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

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

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

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

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

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

2037 case attr::Pcs: {

2038 OS << "pcs(";

2039 QualType t = T->getEquivalentType();

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

2044 OS << ')';

2045 break;

2046 }

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

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

2049 case attr::AMDGPUKernelCall: OS << "amdgpu_kernel"; break;

2050 case attr::IntelOclBicc: OS << "inteloclbicc"; break;

2051 case attr::PreserveMost:

2052 OS << "preserve_most";

2053 break;

2054

2055 case attr::PreserveAll:

2056 OS << "preserve_all";

2057 break;

2058 case attr::M68kRTD:

2059 OS << "m68k_rtd";

2060 break;

2061 case attr::PreserveNone:

2062 OS << "preserve_none";

2063 break;

2064 case attr::RISCVVectorCC:

2065 OS << "riscv_vector_cc";

2066 break;

2067 case attr::NoDeref:

2068 OS << "noderef";

2069 break;

2070 case attr::AcquireHandle:

2071 OS << "acquire_handle";

2072 break;

2073 case attr::ArmMveStrictPolymorphism:

2074 OS << "__clang_arm_mve_strict_polymorphism";

2075 break;

2076 }

2077 OS << "))";

2078}

2079

2081 raw_ostream &OS) {

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

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

2084}

2085

2087 raw_ostream &OS) {

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

2089}

2090

2091void TypePrinter::printHLSLAttributedResourceBefore(

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

2094}

2095

2096void TypePrinter::printHLSLAttributedResourceAfter(

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

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

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

2102 << ")]]";

2103 if (Attrs.IsROV)

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

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

2107

2108 QualType ContainedTy = T->getContainedType();

2109 if (!ContainedTy.isNull()) {

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

2111 printBefore(ContainedTy, OS);

2112 printAfter(ContainedTy, OS);

2113 OS << ")]]";

2114 }

2115}

2116

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

2118 raw_ostream &OS) {

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

2120 spaceBeforePlaceHolder(OS);

2121}

2122

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

2124 raw_ostream &OS) {}

2125

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

2127 raw_ostream &OS) {

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

2129 if (T->qual_empty()) {

2130 bool isFirst = true;

2131 OS << '<';

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

2133 if (isFirst)

2134 isFirst = false;

2135 else

2136 OS << ',';

2137 OS << I->getName();

2138 }

2139 OS << '>';

2140 }

2141

2142 spaceBeforePlaceHolder(OS);

2143}

2144

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

2146 raw_ostream &OS) {}

2147

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

2149 raw_ostream &OS) {

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

2151 T->isKindOfTypeAsWritten())

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

2153

2154 if (T->isKindOfTypeAsWritten())

2155 OS << "__kindof ";

2156

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

2158

2159 if (T->isSpecializedAsWritten()) {

2160 bool isFirst = true;

2161 OS << '<';

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

2163 if (isFirst)

2164 isFirst = false;

2165 else

2166 OS << ",";

2167

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

2169 }

2170 OS << '>';

2171 }

2172

2173 if (T->qual_empty()) {

2174 bool isFirst = true;

2175 OS << '<';

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

2177 if (isFirst)

2178 isFirst = false;

2179 else

2180 OS << ',';

2181 OS << I->getName();

2182 }

2183 OS << '>';

2184 }

2185

2186 spaceBeforePlaceHolder(OS);

2187}

2188

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

2190 raw_ostream &OS) {

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

2192 T->isKindOfTypeAsWritten())

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

2194}

2195

2197 raw_ostream &OS) {

2199

2200

2203 if (HasEmptyPlaceHolder)

2204 OS << ' ';

2205 OS << '*';

2206 }

2207}

2208

2210 raw_ostream &OS) {}

2211

2212static

2214

2217}

2218

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

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

2222}

2223

2226 bool IncludeType) {

2231}

2232

2236 unsigned Depth);

2237

2241 return true;

2242

2243

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

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

2250 }

2251 return false;

2252 }

2253

2254

2255

2256

2260 if (TQual != PatQual)

2261 return false;

2262

2263

2264 {

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

2270 }

2271

2272

2273 if (auto *PTST =

2278 Template = TTST->getTemplateName();

2279 TemplateArgs = TTST->template_arguments();

2280 } else if (auto *CTSD = dyn_cast_or_null(

2282 Template = TemplateName(CTSD->getSpecializedTemplate());

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

2284 } else {

2285 return false;

2286 }

2287

2289 Args, Depth))

2290 return false;

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

2292 return false;

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

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

2296 return false;

2297 return true;

2298 }

2299

2300

2301 return false;

2302}

2303

2304

2305

2310 return false;

2311

2312

2316 return false;

2317

2321

2325 return false;

2326

2329 }

2330

2331 return false;

2332}

2333

2337 unsigned Depth) {

2341 return true;

2342

2344 if (auto *DRE =

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

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

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

2349 }

2350 }

2351

2353 return true;

2354

2356 return false;

2357

2360 Depth);

2361

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

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

2368 }

2369

2370

2371 return false;

2372}

2373

2377 unsigned Depth) {

2378

2380 return true;

2381

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

2383 return TTPD->hasDefaultArgument() &&

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

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

2387 return TTPD->hasDefaultArgument() &&

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

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

2391 return NTTPD->hasDefaultArgument() &&

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

2394 Depth);

2395 }

2396 return false;

2397}

2398

2399template

2400static void

2403

2406 Args.size() <= TPL->size()) {

2408 for (const TA &A : Args)

2411 Args = Args.drop_back();

2412 }

2413

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

2415 if (!IsPack)

2416 OS << '<';

2417

2418 bool NeedSpace = false;

2419 bool FirstArg = true;

2420 for (const auto &Arg : Args) {

2421

2423 llvm::raw_svector_ostream ArgOS(Buf);

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

2427 OS << Comma;

2429 true, ParmIndex);

2430 } else {

2431 if (!FirstArg)

2432 OS << Comma;

2433

2436 Policy, TPL, ParmIndex));

2437 }

2438 StringRef ArgString = ArgOS.str();

2439

2440

2441

2442

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

2444 OS << ' ';

2445

2446 OS << ArgString;

2447

2448

2449

2450 if (!ArgString.empty()) {

2452 FirstArg = false;

2453 }

2454

2455

2456 if (!IsPack)

2457 ParmIndex++;

2458 }

2459

2460 if (!IsPack) {

2461 if (NeedSpace)

2462 OS << ' ';

2463 OS << '>';

2464 }

2465}

2466

2472}

2473

2478 printTo(OS, Args, Policy, TPL, false, 0);

2479}

2480

2485 printTo(OS, Args, Policy, TPL, false, 0);

2486}

2487

2491}

2492

2493

2494

2495

2498 llvm::raw_svector_ostream StrOS(Buf);

2499 print(StrOS, Policy);

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

2501}

2502

2505 return false;

2506

2508 return false;

2509

2511 return false;

2512

2515 return false;

2516

2517 return true;

2518}

2519

2521 switch (AS) {

2523 return "";

2526 return "__global";

2529 return "__local";

2532 return "__private";

2534 return "__constant";

2536 return "__generic";

2539 return "__global_device";

2542 return "__global_host";

2544 return "__device__";

2546 return "__constant__";

2548 return "__shared__";

2550 return "__sptr __ptr32";

2552 return "__uptr __ptr32";

2554 return "__ptr64";

2556 return "__funcref";

2558 return "groupshared";

2559 default:

2561 }

2562}

2563

2564

2565

2566

2568 bool appendSpaceIfNonEmpty) const {

2569 bool addSpace = false;

2570

2572 if (quals) {

2574 addSpace = true;

2575 }

2577 if (addSpace)

2578 OS << ' ';

2579 OS << "__unaligned";

2580 addSpace = true;

2581 }

2583 if (!ASStr.empty()) {

2584 if (addSpace)

2585 OS << ' ';

2586 addSpace = true;

2587

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

2590 else

2591 OS << ASStr;

2592 }

2593

2595 if (addSpace)

2596 OS << ' ';

2597 addSpace = true;

2599 OS << "__weak";

2600 else

2601 OS << "__strong";

2602 }

2605 if (addSpace)

2606 OS << ' ';

2607 addSpace = true;

2608 }

2609

2610 switch (lifetime) {

2615 OS << "__strong";

2616 break;

2617

2620 }

2621 }

2622

2623 if (appendSpaceIfNonEmpty && addSpace)

2624 OS << ' ';

2625}

2626

2629}

2630

2632 std::string S;

2634 return S;

2635}

2636

2639 std::string buffer;

2641 return buffer;

2642}

2643

2645 const Twine &PlaceHolder, unsigned Indentation) const {

2647 Indentation);

2648}

2649

2652 const Twine &PlaceHolder, unsigned Indentation) {

2654 StringRef PH = PlaceHolder.toStringRef(PHBuf);

2655

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

2657}

2658

2662 Policy);

2663}

2664

2666 std::string &buffer,

2669 llvm::raw_svector_ostream StrOS(Buf);

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

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

2672 buffer.swap(str);

2673}

2674

2677 TypePrinter(LangOptions()).print(S.Ty, S.Quals, OS, "");

2678 return OS;

2679}

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)

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 printTo(raw_ostream &OS, ArrayRef< TA > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL, bool IsPack, unsigned ParmIndex)

static const TemplateArgument & getArgument(const TemplateArgument &A)

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

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

static QualType skipTopLevelReferences(QualType T)

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

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

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

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

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 ...

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.

bool hasSameType(QualType T1, QualType T2) const

Determine whether the given types T1 and T2 are equivalent.

QualType getQualifiedType(SplitQualType split) const

Un-split a SplitQualType.

QualType getUnqualifiedArrayType(QualType T, Qualifiers &Quals) const

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

Represents a type which was implicitly adjusted by the semantic engine for arbitrary reasons.

Represents a constant array type that does not decay to a pointer when used as a function parameter.

An attributed type is a type to which a type attribute has been applied.

Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.

A fixed int type of a specified bitwidth.

This class is used for builtin types like 'int'.

Complex values, per C99 6.2.5p11.

Represents the canonical version of C arrays with a specified constant size.

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...

Represents a pointer type decayed from an array or function type.

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

bool isFunctionOrMethod() const

ASTContext & getASTContext() const LLVM_READONLY

bool isImplicit() const

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

SourceLocation getLocation() const

DeclContext * getDeclContext()

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

The name of a declaration.

Represents the type decltype(expr) (C++11).

Represents a C++17 deduced template specialization type.

Represents an extended address space qualifier where the input address space value is dependent.

Represents a qualified type name for which the type name is dependent.

Represents an array type in C++ whose size is a value-dependent expression.

Represents an extended vector type where either the type or size is dependent.

Represents a matrix type where the type and the number of rows and columns is dependent on a template...

Represents a template specialization type whose template cannot be resolved, e.g.

Represents a vector type where either the type or size is dependent.

Represents a type that was referred to using an elaborated type keyword, e.g., struct S,...

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.

This represents one expression.

bool isValueDependent() const

Determines whether the value of this expression depends on.

llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) 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...

bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const

ExtVectorType - Extended vector type.

An immutable set of FunctionEffects and possibly conditions attached to them.

Represents a K&R-style 'int foo()' function, which has no information available about its arguments.

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

ExtParameterInfo getExtParameterInfo(unsigned I) const

ExceptionSpecificationType getExceptionSpecType() const

Get the kind of exception specification on this function.

unsigned getNumParams() const

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

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().

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.

A class which abstracts out some details necessary for making a call.

CallingConv getCC() const

bool getCmseNSCall() const

bool getNoCfCheck() const

unsigned getRegParm() const

bool getNoCallerSavedRegs() const

bool getProducesResult() const

FunctionType - C99 6.7.5.3 - Function Declarators.

ExtInfo getExtInfo() const

static ArmStateValue getArmZT0State(unsigned AttrBits)

static ArmStateValue getArmZAState(unsigned AttrBits)

QualType getReturnType() const

@ SME_PStateSMEnabledMask

@ SME_PStateSMCompatibleMask

@ SME_AgnosticZAStateMask

One of these records is kept for each identifier that is lexed.

StringRef getName() const

Return the actual identifier string.

Represents a C array with an unspecified size.

The injected class name of a C++ class template or class template partial specialization.

An lvalue reference type, per C++11 [dcl.ref].

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

Sugar type that represents a type that was qualified by a qualifier written as a macro invocation.

A pointer to member type per C++ 8.3.3 - Pointers to members.

This represents a decl that may have a name.

StringRef getName() const

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

DeclarationName getDeclName() const

Get the actual, stored name of the declaration, which may be a special name.

Represents a C++ nested name specifier, such as "\::std::vector::".

Interfaces are the core concept in Objective-C for object oriented design.

Represents a pointer to an Objective C object.

Represents a class type in Objective C.

Represents a type parameter type in Objective C.

Represents a pack expansion of types.

Sugar for parentheses used when specifying types.

PointerType - C99 6.7.5.1 - Pointer Declarators.

Represents an unpacked "presumed" location which can be presented to the user.

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

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

QualType getNonReferenceType() const

If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...

QualType getCanonicalType() const

SplitQualType split() const

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

std::string getAsString() const

StreamedQualTypeHelper stream(const PrintingPolicy &Policy, const Twine &PlaceHolder=Twine(), unsigned Indentation=0) const

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

bool isEmptyWhenPrinted(const PrintingPolicy &Policy) const

ObjCLifetime getObjCLifetime() const

std::string getAsString() const

LangAS getAddressSpace() const

static std::string getAddrSpaceAsString(LangAS AS)

An rvalue reference type, per C++11 [dcl.ref].

A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...

Base for LValueReferenceType and RValueReferenceType.

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

Returns the "presumed" location of a SourceLocation specifies.

void printPretty(raw_ostream &OS, PrinterHelper *Helper, const PrintingPolicy &Policy, unsigned Indentation=0, StringRef NewlineSymbol="\n", const ASTContext *Context=nullptr) const

Represents the result of substituting a set of types for a template type parameter pack.

Represents the result of substituting a type for a template type parameter.

Represents the declaration of a struct/union/class/enum.

A convenient class for passing around template argument information.

llvm::ArrayRef< TemplateArgumentLoc > arguments() const

A template argument list.

ArrayRef< TemplateArgument > asArray() const

Produce this as an array ref.

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.

bool getIsDefaulted() const

If returns 'true', this TemplateArgument corresponds to a default template parameter.

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.

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

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

Represents a type template specialization; the template must be a class template, a type alias templa...

Declaration of a template type parameter.

const Type * getTypeForDecl() const

Represents a typeof (or typeof) expression (a C23 feature and GCC extension) or a typeof_unqual expre...

Represents typeof(type), a C23 feature and GCC extension, or `typeof_unqual(type),...

QualType getType() const

Return the type wrapped by this type source info.

static StringRef getKeywordName(ElaboratedTypeKeyword Keyword)

The base class of the type hierarchy.

CXXRecordDecl * getAsCXXRecordDecl() const

Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...

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

TypeClass getTypeClass() const

const T * getAs() const

Member-template getAs'.

Base class for declarations which introduce a typedef-name.

A unary type transform, which is a type constructed from another.

Represents the dependent type named by a dependently-scoped typename using declaration,...

Represents a C array with a specified size that is not an integer-constant-expression.

Represents a GCC generic vector type.

const internal::VariadicAllOfMatcher< Attr > attr

Matches attributes.

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

@ GNUAutoType

__auto_type (GNU extension)

@ DecltypeAuto

decltype(auto)

llvm::StringRef getParameterABISpelling(ParameterABI kind)

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 (&&).

const StreamingDiagnostic & operator<<(const StreamingDiagnostic &DB, const ASTContext::SectionInfo &Section)

Insertion operator for diagnostics.

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.

bool isComputedNoexcept(ExceptionSpecificationType ESpecType)

bool isNoexceptExceptionSpec(ExceptionSpecificationType ESpecType)

LangAS

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

bool isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg, const NamedDecl *Param, ArrayRef< TemplateArgument > Args, unsigned Depth)

Make a best-effort determination of whether the type T can be produced by substituting Args into the ...

const FunctionProtoType * T

void printTemplateArgumentList(raw_ostream &OS, ArrayRef< TemplateArgument > Args, const PrintingPolicy &Policy, const TemplateParameterList *TPL=nullptr)

Print a template argument list, including the '<' and '>' enclosing the template arguments.

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

Determine whether two declarations declare the same entity.

@ None

No keyword precedes the qualified type name.

@ EST_NoThrow

Microsoft __declspec(nothrow) extension.

@ EST_MSAny

Microsoft throw(...) extension.

Represents an explicit template argument list in C++, e.g., the "" in "sort".

llvm::ArrayRef< TemplateArgumentLoc > arguments() const

llvm::dxil::ResourceClass ResourceClass

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

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 PrintCanonicalTypes

Whether to print types as written or canonically.

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 SuppressStrongLifetime

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

unsigned Restrict

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

unsigned SuppressScope

Suppresses printing of scope specifiers.

unsigned IncludeTagDefinition

When true, include the body of a tag definition.

unsigned SuppressLifetimeQualifiers

When true, suppress printing of lifetime qualifier in ARC.

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.