clang: lib/Sema/SemaCast.cpp Source File (original) (raw)

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

28#include "llvm/ADT/SmallVector.h"

29#include "llvm/ADT/StringExtras.h"

30#include

31using namespace clang;

32

33

34

37 TC_Success,

38 TC_Extension,

39

40 TC_Failed

41

43

46}

47

57

58namespace {

59 struct CastOperation {

61 : Self(S), SrcExpr(src), DestType(destType),

64 Kind(CK_Dependent), IsARCUnbridgedCast(false) {

65

66

67

68

69

70

71

72

73

75 !DestType->isArrayType()) {

76 DestType = DestType.getAtomicUnqualifiedType();

77 }

78

81 PlaceholderKind = placeholder->getKind();

82 } else {

84 }

85 }

86

95 bool IsARCUnbridgedCast;

96

99

100

101 void CheckConstCast();

102 void CheckReinterpretCast();

103 void CheckStaticCast();

104 void CheckDynamicCast();

105 void CheckCXXCStyleCast(bool FunctionalCast, bool ListInitialization);

106 void CheckCStyleCast();

107 void CheckBuiltinBitCast();

108 void CheckAddrspaceCast();

109

110 void updatePartOfExplicitCastFlags(CastExpr *CE) {

111

112

113

114 for (; auto *ICE = dyn_cast(CE->getSubExpr()); CE = ICE)

115 ICE->setIsPartOfExplicitCast(true);

116 }

117

118

119

121

122

123 if (IsARCUnbridgedCast) {

125 Self.Context, Self.Context.ARCUnbridgedCastTy, CK_Dependent,

127 Self.CurFPFeatureOverrides());

128 }

129 updatePartOfExplicitCastFlags(castExpr);

131 }

132

133

134

135

136

137

139 if (PlaceholderKind != K) return false;

140

142 return true;

143 }

144

145 bool isPlaceholder() const {

146 return PlaceholderKind != 0;

147 }

149 return PlaceholderKind == K;

150 }

151

152

153 void checkAddressSpaceCast(QualType SrcType, QualType DestType);

154

155 void checkCastAlign() {

156 Self.CheckCastAlign(SrcExpr.get(), DestType, OpRange);

157 }

158

160 assert(Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers());

161

162 Expr *src = SrcExpr.get();

163 if (Self.ObjC().CheckObjCConversion(OpRange, DestType, src, CCK) ==

165 IsARCUnbridgedCast = true;

166 SrcExpr = src;

167 }

168

169

170 void checkNonOverloadPlaceholders() {

171 if (!isPlaceholder() || isPlaceholder(BuiltinType::Overload))

172 return;

173

174 SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());

176 return;

178 }

179 };

180

183 if (const auto *PtrType = dyn_cast(FromType)) {

184 if (PtrType->getPointeeType()->hasAttr(attr::NoDeref)) {

185 if (const auto *DestType = dyn_cast(ToType)) {

186 if (!DestType->getPointeeType()->hasAttr(attr::NoDeref)) {

187 S.Diag(OpLoc, diag::warn_noderef_to_dereferenceable_pointer);

188 }

189 }

190 }

191 }

192 }

193

194 struct CheckNoDerefRAII {

195 CheckNoDerefRAII(CastOperation &Op) : Op(Op) {}

196 ~CheckNoDerefRAII() {

197 if (!Op.SrcExpr.isInvalid())

198 CheckNoDeref(Op.Self, Op.SrcExpr.get()->getType(), Op.ResultType,

199 Op.OpRange.getBegin());

200 }

201

202 CastOperation &Op;

203 };

204}

205

208

209

210

211

212

213

214

215

216

217

218

219

221 QualType DestType, bool CStyle,

224 unsigned &msg);

226 QualType DestType, bool CStyle,

228 unsigned &msg,

232 QualType DestType, bool CStyle,

234 unsigned &msg,

241 QualType OrigDestType, unsigned &msg,

246 QualType DestType,bool CStyle,

248 unsigned &msg,

251

255 unsigned &msg, CastKind &Kind, bool ListInitialization);

260 bool ListInitialization);

262 QualType DestType, bool CStyle,

263 unsigned &msg);

265 QualType DestType, bool CStyle,

269 QualType DestType, bool CStyle,

270 unsigned &msg, CastKind &Kind);

271

278

279 assert(D.isInvalidType());

280

282 if (D.isInvalidType())

284

286

288 }

289

291 SourceRange(LAngleBracketLoc, RAngleBracketLoc),

293}

294

301

302

303 bool TypeDependent =

305

306 CastOperation Op(*this, DestType, E);

308 Op.DestRange = AngleBrackets;

309

310 switch (Kind) {

311 default: llvm_unreachable("Unknown C++ cast!");

312

313 case tok::kw_addrspace_cast:

314 if (!TypeDependent) {

315 Op.CheckAddrspaceCast();

316 if (Op.SrcExpr.isInvalid())

318 }

320 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),

321 DestTInfo, OpLoc, Parens.getEnd(), AngleBrackets));

322

323 case tok::kw_const_cast:

324 if (!TypeDependent) {

325 Op.CheckConstCast();

326 if (Op.SrcExpr.isInvalid())

329 }

331 Op.ValueKind, Op.SrcExpr.get(), DestTInfo,

332 OpLoc, Parens.getEnd(),

333 AngleBrackets));

334

335 case tok::kw_dynamic_cast: {

336

338 return ExprError(Diag(OpLoc, diag::err_openclcxx_not_supported)

339 << "dynamic_cast");

340 }

341

342 if (!TypeDependent) {

343 Op.CheckDynamicCast();

344 if (Op.SrcExpr.isInvalid())

346 }

348 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),

349 &Op.BasePath, DestTInfo,

350 OpLoc, Parens.getEnd(),

351 AngleBrackets));

352 }

353 case tok::kw_reinterpret_cast: {

354 if (!TypeDependent) {

355 Op.CheckReinterpretCast();

356 if (Op.SrcExpr.isInvalid())

359 }

361 Op.ValueKind, Op.Kind, Op.SrcExpr.get(),

362 nullptr, DestTInfo, OpLoc,

364 AngleBrackets));

365 }

366 case tok::kw_static_cast: {

367 if (!TypeDependent) {

368 Op.CheckStaticCast();

369 if (Op.SrcExpr.isInvalid())

372 }

373

375 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),

377 Parens.getEnd(), AngleBrackets));

378 }

379 }

380}

381

385 assert(D.isInvalidType());

386

388 if (D.isInvalidType())

390

392}

393

397 CastOperation Op(*this, TSI->getType(), Operand);

398 Op.OpRange = SourceRange(KWLoc, RParenLoc);

401

403 Op.CheckBuiltinBitCast();

404 if (Op.SrcExpr.isInvalid())

406 }

407

410 Op.SrcExpr.get(), TSI, KWLoc, RParenLoc);

411 return Op.complete(BCE);

412}

413

414

415

419 bool listInitialization) {

420 switch (CT) {

421

426 return false;

427

428

432 break;

433 }

434

437 return false;

438

442 range, listInitialization)

444 listInitialization)

447

448

449

450

451 if (!sequence.Failed())

452 return false;

453

455 default: return false;

456

458

459

460

461

462

463

464

465

466

467

468

469

470

471

472

474 return false;

475 break;

478 break;

479 }

480

482

483 unsigned msg = 0;

485

487 case OR_Success: llvm_unreachable("successful failed overload");

489 if (candidates.empty())

490 msg = diag::err_ovl_no_conversion_in_cast;

491 else

492 msg = diag::err_ovl_no_viable_conversion_in_cast;

494 break;

495

497 msg = diag::err_ovl_ambiguous_conversion_in_cast;

499 break;

500

505 assert(Res == OR_Deleted && "Inconsistent overload resolution");

506

507 StringLiteral *Msg = Best->Function->getDeletedMessage();

510 S.PDiag(diag::err_ovl_deleted_conversion_in_cast)

511 << CT << srcType << destType << (Msg != nullptr)

512 << (Msg ? Msg->getString() : StringRef())

515 return true;

516 }

517 }

518

521 S.PDiag(msg) << CT << srcType << destType << range

523 S, howManyCandidates, src);

524

525 return true;

526}

527

528

531 bool listInitialization) {

532 if (msg == diag::err_bad_cxx_cast_generic &&

534 listInitialization))

535 return;

536

539

540

541 int DifferentPtrness = 0;

545 DifferentPtrness++;

546 }

550 DifferentPtrness--;

551 }

552 if (!DifferentPtrness) {

555 if (RecFrom && RecTo) {

557 if (!DeclFrom->isCompleteDefinition())

558 S.Diag(DeclFrom->getLocation(), diag::note_type_incomplete) << DeclFrom;

560 if (!DeclTo->isCompleteDefinition())

561 S.Diag(DeclTo->getLocation(), diag::note_type_incomplete) << DeclTo;

562 }

563 }

564}

565

566namespace {

567

568

569enum CastAwayConstnessKind {

570

571 CACK_None = 0,

572

573 CACK_Similar = 1,

574

575

576 CACK_SimilarKind = 2,

577

578

579 CACK_Incoherent = 3,

580};

581}

582

583

584

585

586

587

588

589

590

591

592

593

594

595static CastAwayConstnessKind

597 enum { None, Ptr, MemPtr, BlockPtr, Array };

602

603

606 };

607

610 return AT->getElementType();

612 };

613

614 CastAwayConstnessKind Kind;

615

617

618

619

620

622 Kind = CastAwayConstnessKind::CACK_Similar;

624 Kind = CastAwayConstnessKind::CACK_Similar;

625 } else {

626

627 int T1Class = Classify(T1);

628 if (T1Class == None)

629 return CastAwayConstnessKind::CACK_None;

630

631 int T2Class = Classify(T2);

632 if (T2Class == None)

633 return CastAwayConstnessKind::CACK_None;

634

635 T1 = Unwrap(T1);

636 T2 = Unwrap(T2);

637 Kind = T1Class == T2Class ? CastAwayConstnessKind::CACK_SimilarKind

638 : CastAwayConstnessKind::CACK_Incoherent;

639 }

640

641

642

643

644

645 while (true) {

647

648 if (Classify(T1) != Array)

649 break;

650

651 auto T2Class = Classify(T2);

652 if (T2Class == None)

653 break;

654

655 if (T2Class != Array)

656 Kind = CastAwayConstnessKind::CACK_Incoherent;

657 else if (Kind != CastAwayConstnessKind::CACK_Incoherent)

658 Kind = CastAwayConstnessKind::CACK_SimilarKind;

659

660 T1 = Unwrap(T1);

662 }

663

664 return Kind;

665}

666

667

668

669

670

671

672

673static CastAwayConstnessKind

675 bool CheckCVR, bool CheckObjCLifetime,

676 QualType *TheOffendingSrcType = nullptr,

677 QualType *TheOffendingDestType = nullptr,

678 Qualifiers *CastAwayQualifiers = nullptr) {

679

680

681 if (!CheckCVR && CheckObjCLifetime && Self.Context.getLangOpts().ObjC)

682 return CastAwayConstnessKind::CACK_None;

683

687 "Source type is not pointer or pointer to member.");

690 "Destination type is not pointer or pointer to member.");

691 }

692

693 QualType UnwrappedSrcType = Self.Context.getCanonicalType(SrcType),

694 UnwrappedDestType = Self.Context.getCanonicalType(DestType);

695

696

697

698

699 QualType PrevUnwrappedSrcType = UnwrappedSrcType;

700 QualType PrevUnwrappedDestType = UnwrappedDestType;

701 auto WorstKind = CastAwayConstnessKind::CACK_Similar;

702 bool AllConstSoFar = true;

704 Self.Context, UnwrappedSrcType, UnwrappedDestType)) {

705

706

707 if (Kind > WorstKind)

708 WorstKind = Kind;

709

710

712 Self.Context.getUnqualifiedArrayType(UnwrappedSrcType, SrcQuals);

713 Self.Context.getUnqualifiedArrayType(UnwrappedDestType, DestQuals);

714

715

716

717

719 UnwrappedDestType->isObjCObjectType())

721

722 if (CheckCVR) {

727

728 if (SrcCvrQuals != DestCvrQuals) {

729 if (CastAwayQualifiers)

730 *CastAwayQualifiers = SrcCvrQuals - DestCvrQuals;

731

732

733 if (!DestCvrQuals.compatiblyIncludes(SrcCvrQuals,

734 Self.getASTContext())) {

735 if (TheOffendingSrcType)

736 *TheOffendingSrcType = PrevUnwrappedSrcType;

737 if (TheOffendingDestType)

738 *TheOffendingDestType = PrevUnwrappedDestType;

739 return WorstKind;

740 }

741

742

743

744 if (!AllConstSoFar)

745 return WorstKind;

746 }

747 }

748

749 if (CheckObjCLifetime &&

751 return WorstKind;

752

753

754

755 if (AllConstSoFar && !DestQuals.hasConst()) {

756 AllConstSoFar = false;

757 if (TheOffendingSrcType)

758 *TheOffendingSrcType = PrevUnwrappedSrcType;

759 if (TheOffendingDestType)

760 *TheOffendingDestType = PrevUnwrappedDestType;

761 }

762

763 PrevUnwrappedSrcType = UnwrappedSrcType;

764 PrevUnwrappedDestType = UnwrappedDestType;

765 }

766

767 return CastAwayConstnessKind::CACK_None;

768}

769

771 unsigned &DiagID) {

772 switch (CACK) {

773 case CastAwayConstnessKind::CACK_None:

774 llvm_unreachable("did not cast away constness");

775

776 case CastAwayConstnessKind::CACK_Similar:

777

778 case CastAwayConstnessKind::CACK_SimilarKind:

779 DiagID = diag::err_bad_cxx_cast_qualifiers_away;

781

782 case CastAwayConstnessKind::CACK_Incoherent:

783 DiagID = diag::ext_bad_cxx_cast_qualifiers_away_incoherent;

785 }

786

787 llvm_unreachable("unexpected cast away constness kind");

788}

789

790

791

792

793void CastOperation::CheckDynamicCast() {

794 CheckNoDerefRAII NoderefCheck(*this);

795

797 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());

798 else if (isPlaceholder())

799 SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());

800 if (SrcExpr.isInvalid())

801 return;

802

803 QualType OrigSrcType = SrcExpr.get()->getType();

804 QualType DestType = Self.Context.getCanonicalType(this->DestType);

805

806

807

808

812 if (DestPointer) {

816 } else {

817 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ref_or_ptr)

818 << this->DestType << DestRange;

820 return;

821 }

822

825 assert(DestPointer && "Reference to void is not possible");

826 } else if (DestRecord) {

827 if (Self.RequireCompleteType(OpRange.getBegin(), DestPointee,

828 diag::err_bad_cast_incomplete,

829 DestRange)) {

831 return;

832 }

833 } else {

834 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)

837 return;

838 }

839

840

841

842

843

844 QualType SrcType = Self.Context.getCanonicalType(OrigSrcType);

846 if (DestPointer) {

849 } else {

850 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_ptr)

851 << OrigSrcType << this->DestType << SrcExpr.get()->getSourceRange();

853 return;

854 }

855 } else if (DestReference->isLValueReferenceType()) {

856 if (!SrcExpr.get()->isLValue()) {

857 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_rvalue)

858 << CT_Dynamic << OrigSrcType << this->DestType << OpRange;

859 }

860 SrcPointee = SrcType;

861 } else {

862

863

864 if (SrcExpr.get()->isPRValue())

865 SrcExpr = Self.CreateMaterializeTemporaryExpr(

866 SrcType, SrcExpr.get(), false);

867 SrcPointee = SrcType;

868 }

869

871 if (SrcRecord) {

872 if (Self.RequireCompleteType(OpRange.getBegin(), SrcPointee,

873 diag::err_bad_cast_incomplete,

874 SrcExpr.get())) {

876 return;

877 }

878 } else {

879 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_class)

880 << SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange();

882 return;

883 }

884

885 assert((DestPointer || DestReference) &&

886 "Bad destination non-ptr/ref slipped through.");

887 assert((DestRecord || DestPointee->isVoidType()) &&

888 "Bad destination pointee slipped through.");

889 assert(SrcRecord && "Bad source pointee slipped through.");

890

891

893 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_qualifiers_away)

894 << CT_Dynamic << OrigSrcType << this->DestType << OpRange;

896 return;

897 }

898

899

900

901 if (DestRecord == SrcRecord) {

902 Kind = CK_NoOp;

903 return;

904 }

905

906

907

908 if (DestRecord &&

909 Self.IsDerivedFrom(OpRange.getBegin(), SrcPointee, DestPointee)) {

910 if (Self.CheckDerivedToBaseConversion(SrcPointee, DestPointee,

911 OpRange.getBegin(), OpRange,

912 &BasePath)) {

914 return;

915 }

916

917 Kind = CK_DerivedToBase;

918 return;

919 }

920

921

923 assert(SrcDecl && "Definition missing");

924 if (!cast(SrcDecl)->isPolymorphic()) {

925 Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)

926 << SrcPointee.getUnqualifiedType() << SrcExpr.get()->getSourceRange();

928 }

929

930

931

932

933 if (Self.getLangOpts().RTTI && !DestPointee->isVoidType()) {

934 Self.Diag(OpRange.getBegin(), diag::err_no_dynamic_cast_with_fno_rtti);

936 return;

937 }

938

939

940 if (Self.getLangOpts().RTTIData) {

941 bool MicrosoftABI =

942 Self.getASTContext().getTargetInfo().getCXXABI().isMicrosoft();

943 bool isClangCL = Self.getDiagnostics().getDiagnosticOptions().getFormat() ==

945 if (MicrosoftABI || !DestPointee->isVoidType())

946 Self.Diag(OpRange.getBegin(),

947 diag::warn_no_dynamic_cast_with_rtti_disabled)

948 << isClangCL;

949 }

950

951

952

953 if (DestRecord) {

955 if (DestDecl->isEffectivelyFinal())

956 Self.MarkVTableUsed(OpRange.getBegin(), DestDecl);

957 }

958

959

960 Kind = CK_Dynamic;

961}

962

963

964

965

966

967

968void CastOperation::CheckConstCast() {

969 CheckNoDerefRAII NoderefCheck(*this);

970

972 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());

973 else if (isPlaceholder())

974 SrcExpr = Self.CheckPlaceholderExpr(SrcExpr.get());

975 if (SrcExpr.isInvalid())

976 return;

977

978 unsigned msg = diag::err_bad_cxx_cast_generic;

979 auto TCR = TryConstCast(Self, SrcExpr, DestType, false, msg);

981 Self.Diag(OpRange.getBegin(), msg) << CT_Const

982 << SrcExpr.get()->getType() << DestType << OpRange;

983 }

986}

987

988void CastOperation::CheckAddrspaceCast() {

989 unsigned msg = diag::err_bad_cxx_cast_generic;

990 auto TCR =

993 Self.Diag(OpRange.getBegin(), msg)

994 << CT_Addrspace << SrcExpr.get()->getType() << DestType << OpRange;

995 }

998}

999

1000

1001

1006

1007

1011

1012

1013

1014

1016 return;

1017

1019

1021 return;

1022

1023 enum {

1024 ReinterpretUpcast,

1025 ReinterpretDowncast

1026 } ReinterpretKind;

1027

1029

1031 ReinterpretKind = ReinterpretUpcast;

1032 else if (DestRD->isDerivedFrom(SrcRD, BasePaths))

1033 ReinterpretKind = ReinterpretDowncast;

1034 else

1035 return;

1036

1038 bool NonZeroOffset = false;

1040 E = BasePaths.end();

1041 I != E; ++I) {

1044 bool IsVirtual = false;

1045 for (CXXBasePath::const_iterator IElem = Path.begin(), EElem = Path.end();

1046 IElem != EElem; ++IElem) {

1047 IsVirtual = IElem->Base->isVirtual();

1048 if (IsVirtual)

1049 break;

1050 const CXXRecordDecl *BaseRD = IElem->Base->getType()->getAsCXXRecordDecl();

1051 assert(BaseRD && "Base type should be a valid unqualified class type");

1052

1053

1055 *ClassDefinition = Class->getDefinition();

1056 if (Class->isInvalidDecl() || !ClassDefinition ||

1057 !ClassDefinition->isCompleteDefinition())

1058 return;

1059

1061 Self.Context.getASTRecordLayout(Class);

1063 }

1064 if (!IsVirtual) {

1065

1066 if (Offset.isZero())

1067 return;

1068

1069 else

1070 NonZeroOffset = true;

1071 }

1073 }

1074

1075 (void) NonZeroOffset;

1076 assert((VirtualBase || NonZeroOffset) &&

1077 "Should have returned if has non-virtual base with zero offset");

1078

1080 ReinterpretKind == ReinterpretUpcast? DestType : SrcType;

1082 ReinterpretKind == ReinterpretUpcast? SrcType : DestType;

1083

1085 Self.Diag(BeginLoc, diag::warn_reinterpret_different_from_static)

1086 << DerivedType << BaseType << VirtualBase << int(ReinterpretKind)

1087 << OpRange;

1088 Self.Diag(BeginLoc, diag::note_reinterpret_updowncast_use_static)

1089 << int(ReinterpretKind)

1091}

1092

1096 return true;

1097

1098

1103 return true;

1104

1106}

1107

1110 unsigned int DiagID = 0;

1111 const unsigned int DiagList[] = {diag::warn_cast_function_type_strict,

1112 diag::warn_cast_function_type};

1115 DiagID = ID;

1116 break;

1117 }

1118 }

1119 if (!DiagID)

1120 return 0;

1121

1134 } else {

1135 return 0;

1136 }

1137 assert(SrcFTy && DstFTy);

1138

1139 if (Self.Context.hasSameType(SrcFTy, DstFTy))

1140 return 0;

1141

1142

1143 if (DiagID == diag::warn_cast_function_type_strict)

1144 return DiagID;

1145

1148 return false;

1150 return !PT->isVariadic() && PT->getNumParams() == 0;

1151 return false;

1152 };

1153

1154

1155 if (IsVoidVoid(SrcFTy) || IsVoidVoid(DstFTy))

1156 return 0;

1157

1158

1160 Self.Context))

1161 return DiagID;

1162

1163

1165 return 0;

1166

1167

1168

1169 const auto *SrcFPTy = cast(SrcFTy);

1170 const auto *DstFPTy = cast(DstFTy);

1171

1172

1173

1174 unsigned NumParams = SrcFPTy->getNumParams();

1175 unsigned DstNumParams = DstFPTy->getNumParams();

1176 if (NumParams > DstNumParams) {

1177 if (!DstFPTy->isVariadic())

1178 return DiagID;

1179 NumParams = DstNumParams;

1180 } else if (NumParams < DstNumParams) {

1181 if (!SrcFPTy->isVariadic())

1182 return DiagID;

1183 }

1184

1185 for (unsigned i = 0; i < NumParams; ++i)

1187 DstFPTy->getParamType(i), Self.Context))

1188 return DiagID;

1189

1190 return 0;

1191}

1192

1193

1194

1195

1196

1197

1198void CastOperation::CheckReinterpretCast() {

1199 if (ValueKind == VK_PRValue && !isPlaceholder(BuiltinType::Overload))

1200 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());

1201 else

1202 checkNonOverloadPlaceholders();

1203 if (SrcExpr.isInvalid())

1204 return;

1205

1206 unsigned msg = diag::err_bad_cxx_cast_generic;

1209 false, OpRange, msg, Kind);

1210 if (tcr != TC_Success && msg != 0) {

1211 if (SrcExpr.isInvalid())

1212 return;

1213 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {

1214

1215 Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_overload)

1217 << DestType << OpRange;

1218 Self.NoteAllOverloadCandidates(SrcExpr.get());

1219

1220 } else {

1222 DestType, false);

1223 }

1224 }

1225

1227 if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())

1230

1232 Self.Diag(OpRange.getBegin(), DiagID)

1233 << SrcExpr.get()->getType() << DestType << OpRange;

1234 } else {

1236 }

1237}

1238

1239

1240

1241

1242

1243void CastOperation::CheckStaticCast() {

1244 CheckNoDerefRAII NoderefCheck(*this);

1245

1246 if (isPlaceholder()) {

1247 checkNonOverloadPlaceholders();

1248 if (SrcExpr.isInvalid())

1249 return;

1250 }

1251

1252

1253

1254

1256 Kind = CK_ToVoid;

1257

1258 if (claimPlaceholder(BuiltinType::Overload)) {

1259 Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr,

1260 false,

1261 true,

1262 OpRange, DestType, diag::err_bad_static_cast_overload);

1263 if (SrcExpr.isInvalid())

1264 return;

1265 }

1266

1267 SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());

1268 return;

1269 }

1270

1272 !isPlaceholder(BuiltinType::Overload)) {

1273 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());

1274 if (SrcExpr.isInvalid())

1275 return;

1276 }

1277

1278 unsigned msg = diag::err_bad_cxx_cast_generic;

1281 OpRange, msg, Kind, BasePath, false);

1282 if (tcr != TC_Success && msg != 0) {

1283 if (SrcExpr.isInvalid())

1284 return;

1285 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {

1287 Self.Diag(OpRange.getBegin(), diag::err_bad_static_cast_overload)

1288 << oe->getName() << DestType << OpRange

1290 Self.NoteAllOverloadCandidates(SrcExpr.get());

1291 } else {

1293 false);

1294 }

1295 }

1296

1298 if (Kind == CK_BitCast)

1299 checkCastAlign();

1300 if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())

1302 } else {

1304 }

1305}

1306

1309 if (!SrcPtrType)

1310 return false;

1312 if (!DestPtrType)

1313 return false;

1315 DestPtrType->getPointeeType().getAddressSpace();

1316}

1317

1318

1319

1320

1325 bool ListInitialization) {

1326

1329

1330

1331

1332

1333

1334

1335

1336

1337

1338

1339

1340

1341

1342

1343

1344

1346

1347

1348

1349

1351 OpRange, msg, Kind, BasePath);

1353 return tcr;

1354

1355

1356

1357

1359 BasePath, msg);

1361 return tcr;

1362

1363

1364

1366 Kind, ListInitialization);

1370 return tcr;

1371

1372

1373

1374

1375

1376

1377

1378

1379

1380

1381

1383

1384

1385

1386

1388 if (Enum->getDecl()->isScoped()) {

1390 Kind = CK_IntegralToBoolean;

1393 Kind = CK_IntegralCast;

1396 Kind = CK_IntegralToFloating;

1398 }

1399 }

1400 }

1401

1402

1403

1404

1405

1406

1407

1408

1409

1411 if (Self.RequireCompleteType(OpRange.getBegin(), DestType,

1412 diag::err_bad_cast_incomplete)) {

1415 }

1417

1418

1420 Kind = Enum->getDecl()->isFixed() &&

1421 Enum->getDecl()->getIntegerType()->isBooleanType()

1422 ? CK_IntegralToBoolean

1423 : CK_IntegralCast;

1426 Kind = CK_FloatingToIntegral;

1428 }

1429 }

1430

1431

1432

1434 Kind, BasePath);

1436 return tcr;

1437

1438

1439

1440

1442 OpRange, msg, Kind, BasePath);

1444 return tcr;

1445

1446

1447

1448

1455

1456

1457

1458 if (!CStyle) {

1465 if (DestPointeeQuals != SrcPointeeQuals &&

1467 Self.getASTContext())) {

1468 msg = diag::err_bad_cxx_cast_qualifiers_away;

1470 }

1471 }

1473 ? CK_AddressSpaceConversion

1474 : CK_BitCast;

1476 }

1477

1478

1479

1480 if (!CStyle && Self.getLangOpts().MSVCCompat &&

1482 Self.Diag(OpRange.getBegin(), diag::ext_ms_cast_fn_obj) << OpRange;

1483 Kind = CK_BitCast;

1485 }

1486 }

1488

1489

1490 Kind = CK_CPointerToObjCPointerCast;

1492 }

1494

1495 Kind = CK_AnyPointerToBlockPointerCast;

1497 }

1498 }

1499 }

1500

1503 Kind = CK_BitCast;

1505 }

1506

1507

1508 if (!CStyle &&

1509 Self.ObjC().CheckTollFreeBridgeStaticCast(DestType, SrcExpr.get(), Kind))

1511

1512

1513

1516 if (SrcPointer->getPointeeType()->getAs<RecordType>() &&

1518 msg = diag::err_bad_cxx_cast_unrelated_class;

1519

1521 if (Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind)) {

1524 }

1526 }

1527

1528

1530}

1531

1532

1534 QualType DestType, bool CStyle,

1536 unsigned &msg) {

1537

1538

1539

1541 if (!R)

1543

1546

1547

1548

1549

1552 if (CStyle) {

1555 }

1556

1559 SrcExpr->getBeginLoc(), ToType, FromType, &RefConv);

1563

1564

1565

1566 msg = SrcExpr->isLValue() ? diag::err_bad_lvalue_to_rvalue_cast

1567 : diag::err_bad_rvalue_to_rvalue_cast;

1569 }

1570

1571 if (RefConv & Sema::ReferenceConversions::DerivedToBase) {

1572 Kind = CK_DerivedToBase;

1573 CXXBasePaths Paths(true, true,

1574 true);

1578

1579 Self.BuildBasePathArray(Paths, BasePath);

1580 } else

1581 Kind = CK_NoOp;

1582

1584}

1585

1586

1590 unsigned &msg, CastKind &Kind,

1592

1593

1594

1595

1596

1597

1598

1599

1600

1602 if (!DestReference) {

1604 }

1606 if (!RValueRef && !SrcExpr->isLValue()) {

1607

1608 msg = diag::err_bad_cxx_cast_rvalue;

1610 }

1611

1613

1614

1615

1616

1618 Self.Context.getCanonicalType(SrcExpr->getType()),

1619 Self.Context.getCanonicalType(DestPointee), CStyle,

1620 OpRange, SrcExpr->getType(), DestType, msg, Kind,

1621 BasePath);

1622}

1623

1624

1628 unsigned &msg, CastKind &Kind,

1630

1631

1632

1633

1634

1635

1636

1637

1639 if (!DestPointer) {

1641 }

1642

1644 if (!SrcPointer) {

1645 msg = diag::err_bad_static_cast_pointer_nonpointer;

1647 }

1648

1652 CStyle, OpRange, SrcType, DestType, msg, Kind,

1653 BasePath);

1654}

1655

1656

1657

1658

1662 QualType OrigDestType, unsigned &msg,

1664

1665 if (Self.isCompleteType(OpRange.getBegin(), SrcType) ||

1666 Self.isCompleteType(OpRange.getBegin(), DestType))

1668

1669

1672 }

1673

1674 CXXBasePaths Paths(true, true,

1675 true);

1676 if (Self.IsDerivedFrom(OpRange.getBegin(), DestType, SrcType, Paths)) {

1678 }

1679

1680

1681

1682

1683

1684

1685

1686

1687

1688

1689

1690

1691

1692

1693

1694

1695

1696

1697

1698

1699 if (!CStyle &&

1701 msg = diag::err_bad_cxx_cast_qualifiers_away;

1703 }

1704

1706

1707

1708

1709

1710 if (!Paths.isRecordingPaths()) {

1711 Paths.clear();

1712 Paths.setRecordingPaths(true);

1713 Self.IsDerivedFrom(OpRange.getBegin(), DestType, SrcType, Paths);

1714 }

1715 std::string PathDisplayStr;

1716 std::set DisplayedPaths;

1718 if (DisplayedPaths.insert(Path.back().SubobjectNumber).second) {

1719

1720

1721 PathDisplayStr += "\n ";

1723 PathDisplayStr += PE.Base->getType().getAsString() + " -> ";

1725 }

1726 }

1727

1728 Self.Diag(OpRange.getBegin(), diag::err_ambiguous_base_to_derived_cast)

1731 << PathDisplayStr << OpRange;

1732 msg = 0;

1734 }

1735

1736 if (Paths.getDetectedVirtual() != nullptr) {

1738 Self.Diag(OpRange.getBegin(), diag::err_static_downcast_via_virtual)

1739 << OrigSrcType << OrigDestType << VirtualBase << OpRange;

1740 msg = 0;

1742 }

1743

1744 if (!CStyle) {

1745 switch (Self.CheckBaseClassAccess(OpRange.getBegin(),

1746 SrcType, DestType,

1747 Paths.front(),

1748 diag::err_downcast_from_inaccessible_base)) {

1752 break;

1753

1755 msg = 0;

1757 }

1758 }

1759

1760 Self.BuildBasePathArray(Paths, BasePath);

1761 Kind = CK_BaseToDerived;

1763}

1764

1765

1766

1767

1768

1769

1770

1771

1774 QualType DestType, bool CStyle,

1776 unsigned &msg, CastKind &Kind,

1779 if (!DestMemPtr)

1781

1782 bool WasOverloadedFunction = false;

1784 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {

1786 = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(), DestType, false,

1787 FoundOverload)) {

1789 SrcType = Self.Context.getMemberPointerType(Fn->getType(),

1790 Self.Context.getTypeDeclType(M->getParent()).getTypePtr());

1791 WasOverloadedFunction = true;

1792 }

1793 }

1794

1796 if (!SrcMemPtr) {

1797 msg = diag::err_bad_static_cast_member_pointer_nonmp;

1799 }

1800

1801

1802

1803 if (Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) {

1804 (void)Self.isCompleteType(OpRange.getBegin(), SrcType);

1805 (void)Self.isCompleteType(OpRange.getBegin(), DestType);

1806 }

1807

1808

1809 if (Self.Context.hasSameUnqualifiedType(SrcMemPtr->getPointeeType(),

1812

1813

1816 CXXBasePaths Paths(true, true,

1817 true);

1818 if (Self.IsDerivedFrom(OpRange.getBegin(), SrcClass, DestClass, Paths))

1820

1821

1822 if (Paths.isAmbiguous(Self.Context.getCanonicalType(DestClass))) {

1823 Paths.clear();

1824 Paths.setRecordingPaths(true);

1825 bool StillOkay =

1826 Self.IsDerivedFrom(OpRange.getBegin(), SrcClass, DestClass, Paths);

1827 assert(StillOkay);

1828 (void)StillOkay;

1829 std::string PathDisplayStr = Self.getAmbiguousPathsDisplayString(Paths);

1830 Self.Diag(OpRange.getBegin(), diag::err_ambiguous_memptr_conv)

1831 << 1 << SrcClass << DestClass << PathDisplayStr << OpRange;

1832 msg = 0;

1834 }

1835

1836 if (const RecordType *VBase = Paths.getDetectedVirtual()) {

1837 Self.Diag(OpRange.getBegin(), diag::err_memptr_conv_via_virtual)

1838 << SrcClass << DestClass << QualType(VBase, 0) << OpRange;

1839 msg = 0;

1841 }

1842

1843 if (!CStyle) {

1844 switch (Self.CheckBaseClassAccess(OpRange.getBegin(),

1845 DestClass, SrcClass,

1846 Paths.front(),

1847 diag::err_upcast_to_inaccessible_base)) {

1851

1852

1853 break;

1854

1856 msg = 0;

1858 }

1859 }

1860

1861 if (WasOverloadedFunction) {

1862

1863

1864 FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(),

1865 DestType,

1866 true,

1867 FoundOverload);

1868 if (!Fn) {

1869 msg = 0;

1871 }

1872

1873 SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr, FoundOverload, Fn);

1875 msg = 0;

1877 }

1878 }

1879

1880 Self.BuildBasePathArray(Paths, BasePath);

1881 Kind = CK_DerivedToBaseMemberPointer;

1883}

1884

1885

1886

1887

1888

1889

1894 CastKind &Kind, bool ListInitialization) {

1896 if (Self.RequireCompleteType(OpRange.getBegin(), DestType,

1897 diag::err_bad_cast_incomplete) ||

1898 Self.RequireNonAbstractType(OpRange.getBegin(), DestType,

1899 diag::err_allocation_of_abstract_type)) {

1900 msg = 0;

1902 }

1903 }

1904

1909 ListInitialization)

1912 ListInitialization)

1914 Expr *SrcExprRaw = SrcExpr.get();

1915

1916

1917

1919

1920

1921

1922

1923

1924

1929

1931 if (Result.isInvalid()) {

1932 msg = 0;

1934 }

1935

1937 Kind = CK_ConstructorConversion;

1938 else

1939 Kind = CK_NoOp;

1940

1943}

1944

1945

1946

1948 QualType DestType, bool CStyle,

1949 unsigned &msg) {

1950 DestType = Self.Context.getCanonicalType(DestType);

1952 bool NeedToMaterializeTemporary = false;

1953

1955

1956

1957

1958

1959

1960

1961

1962

1963

1964

1965

1966 if (isa(DestTypeTmp) && !SrcExpr.get()->isLValue()) {

1967

1968

1969

1970 msg = diag::err_bad_cxx_cast_rvalue;

1972 }

1973

1974 if (isa(DestTypeTmp) && SrcExpr.get()->isPRValue()) {

1976

1977

1978 msg = diag::err_bad_cxx_cast_rvalue;

1980 }

1981

1982

1983

1984 NeedToMaterializeTemporary = true;

1985 }

1986

1987

1988

1989

1990

1991

1993 msg = diag::err_bad_cxx_cast_bitfield;

1995 }

1996

1997 DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType());

1998 SrcType = Self.Context.getPointerType(SrcType);

1999 }

2000

2001

2002

2003

2007

2008

2009

2010

2011

2012 if (!CStyle)

2013 msg = diag::err_bad_const_cast_dest;

2015 }

2018

2019

2020

2021 if (!CStyle)

2022 msg = diag::err_bad_const_cast_dest;

2024 }

2025

2026

2027

2028

2029

2030

2031

2032 if (Self.Context.hasCvrSimilarType(SrcType, DestType))

2034

2035 if (NeedToMaterializeTemporary)

2036

2037

2038 SrcExpr = Self.CreateMaterializeTemporaryExpr(SrcExpr.get()->getType(),

2039 SrcExpr.get(),

2040 false);

2041

2043}

2044

2045

2046

2047

2048

2049

2051 bool IsDereference,

2053 unsigned DiagID = IsDereference ?

2054 diag::warn_pointer_indirection_from_incompatible_type :

2055 diag::warn_undefined_reinterpret_cast;

2056

2058 return;

2059

2061 if (IsDereference) {

2063 return;

2064 }

2067 } else {

2069 return;

2070 }

2071 SrcTy = SrcType;

2073 }

2074

2075

2077 return;

2078 }

2079

2082 return;

2083 }

2084

2086 return;

2087 }

2088

2089

2093 return;

2094 }

2095 }

2096

2098 return;

2099 }

2100

2102}

2103

2107 if (Self.Context.hasSameType(SrcType, DestType))

2108 return;

2110 if (SrcPtrTy->isObjCSelType()) {

2112 if (isa(DestType))

2116 diag::warn_cast_pointer_from_sel)

2118 }

2119}

2120

2121

2122

2125

2126

2128 if (Self.Context.hasSameType(SrcType, DstType) ||

2130 return;

2131 const auto *SrcFTy =

2133 const auto *DstFTy =

2137 if (SrcCC == DstCC)

2138 return;

2139

2140

2141

2143 if (auto *UO = dyn_cast(Src))

2144 if (UO->getOpcode() == UO_AddrOf)

2146 auto *DRE = dyn_cast(Src);

2147 if (!DRE)

2148 return;

2149 auto *FD = dyn_cast(DRE->getDecl());

2150 if (!FD)

2151 return;

2152

2153

2154

2155

2156

2157 CallingConv DefaultCC = Self.getASTContext().getDefaultCallingConvention(

2158 FD->isVariadic(), FD->isCXXInstanceMember());

2159 if (DstCC == DefaultCC || SrcCC != DefaultCC)

2160 return;

2161

2162

2165 Self.Diag(OpRange.getBegin(), diag::warn_cast_calling_conv)

2166 << SrcCCName << DstCCName << OpRange;

2167

2168

2169

2170

2171 if (Self.Diags.isIgnored(diag::warn_cast_calling_conv, OpRange.getBegin()))

2172 return;

2173

2174

2175

2176

2177

2178 SourceLocation NameLoc = FD->getFirstDecl()->getNameInfo().getLoc();

2182 llvm::raw_svector_ostream OS(CCAttrText);

2183 if (Self.getLangOpts().MicrosoftExt) {

2184

2185 OS << "__" << DstCCName;

2187 AttrTokens.push_back(II->isKeyword(Self.getLangOpts())

2190 } else {

2191

2192 OS << "__attribute__((" << DstCCName << "))";

2193 AttrTokens.push_back(tok::kw___attribute);

2194 AttrTokens.push_back(tok::l_paren);

2195 AttrTokens.push_back(tok::l_paren);

2197 AttrTokens.push_back(II->isKeyword(Self.getLangOpts())

2200 AttrTokens.push_back(tok::r_paren);

2201 AttrTokens.push_back(tok::r_paren);

2202 }

2204 if (!AttrSpelling.empty())

2205 CCAttrText = AttrSpelling;

2206 OS << ' ';

2207 Self.Diag(NameLoc, diag::note_change_calling_conv_fixit)

2209}

2210

2215

2216

2217

2218

2223 && Self.Context.getTypeSize(DestType) >

2224 Self.Context.getTypeSize(SrcType)) {

2225

2226

2227

2228

2229

2231 diag::warn_int_to_void_pointer_cast

2232 : diag::warn_int_to_pointer_cast;

2233 Self.Diag(OpRange.getBegin(), Diag) << SrcType << DestType << OpRange;

2234 }

2235}

2236

2239

2240

2241

2242

2243

2244

2246

2247

2248 if (Self.ResolveAndFixSingleFunctionTemplateSpecialization(

2252 ) &&

2254 return true;

2255

2256

2257

2259 if (Self.resolveAndFixAddressOfSingleOverloadCandidate(

2260 Result, true))

2261 return false;

2262 return Result.isUsable();

2263}

2264

2266 QualType DestType, bool CStyle,

2268 unsigned &msg,

2270 bool IsLValueCast = false;

2271

2272 DestType = Self.Context.getCanonicalType(DestType);

2274

2275

2276

2277 if (SrcType == Self.Context.OverloadTy) {

2281

2282 assert(FixedExpr.isUsable() && "Invalid result fixing overloaded expr");

2283 SrcExpr = FixedExpr;

2285 }

2286

2289

2290

2291 msg = diag::err_bad_cxx_cast_rvalue;

2293 }

2294

2295 if (!CStyle) {

2296 Self.CheckCompatibleReinterpretCast(SrcType, DestType,

2297 false, OpRange);

2298 }

2299

2300

2301

2302

2303

2304 const char *inappropriate = nullptr;

2307 break;

2309 msg = diag::err_bad_cxx_cast_bitfield;

2311

2314 inappropriate = "matrix element";

2315 break;

2316 case OK_ObjCProperty: inappropriate = "property expression"; break;

2317 case OK_ObjCSubscript: inappropriate = "container subscripting expression";

2318 break;

2319 }

2320 if (inappropriate) {

2321 Self.Diag(OpRange.getBegin(), diag::err_bad_reinterpret_cast_reference)

2322 << inappropriate << DestType

2326 }

2327

2328

2329 DestType = Self.Context.getPointerType(DestTypeTmp->getPointeeType());

2330 SrcType = Self.Context.getPointerType(SrcType);

2331

2332 IsLValueCast = true;

2333 }

2334

2335

2336 SrcType = Self.Context.getCanonicalType(SrcType);

2337

2340 if (DestMemPtr && SrcMemPtr) {

2341

2342

2343

2344

2346 SrcMemPtr->isMemberFunctionPointer())

2348

2349 if (Self.Context.getTargetInfo().getCXXABI().isMicrosoft()) {

2350

2351

2352 (void)Self.isCompleteType(OpRange.getBegin(), SrcType);

2353 (void)Self.isCompleteType(OpRange.getBegin(), DestType);

2354 }

2355

2356

2357 if (Self.Context.getTypeSize(DestMemPtr) !=

2358 Self.Context.getTypeSize(SrcMemPtr)) {

2359 msg = diag::err_bad_cxx_cast_member_pointer_size;

2361 }

2362

2363

2364

2365

2366

2367 if (auto CACK =

2369 CStyle))

2371

2372

2373 assert(!IsLValueCast);

2374 Kind = CK_ReinterpretMemberPointer;

2376 }

2377

2378

2380

2381

2382

2383

2384 if (Self.Context.getTypeSize(SrcType) >

2385 Self.Context.getTypeSize(DestType)) {

2386 msg = diag::err_bad_reinterpret_cast_small_int;

2388 }

2389 Kind = CK_PointerToIntegral;

2391 }

2392

2393

2394

2395 bool destIsVector = DestType->isVectorType();

2397 if (srcIsVector || destIsVector) {

2398

2399 if (Self.isValidSveBitcast(SrcType, DestType)) {

2400 Kind = CK_BitCast;

2402 }

2403

2404

2405 if (Self.RISCV().isValidRVVBitcast(SrcType, DestType)) {

2406 Kind = CK_BitCast;

2408 }

2409

2410

2411

2412

2416

2417

2418

2419 if (Self.areLaxCompatibleVectorTypes(SrcType, DestType)) {

2420 Kind = CK_BitCast;

2422 }

2423

2424 if (Self.LangOpts.OpenCL && !CStyle) {

2426

2427 if (Self.areVectorTypesSameSize(SrcType, DestType)) {

2428 Kind = CK_BitCast;

2430 }

2431 }

2432 }

2433

2434

2435 if (!destIsVector)

2436 msg = diag::err_bad_cxx_cast_vector_to_scalar_different_size;

2437 else if (!srcIsVector)

2438 msg = diag::err_bad_cxx_cast_scalar_to_vector_different_size;

2439 else

2440 msg = diag::err_bad_cxx_cast_vector_to_vector_different_size;

2441

2443 }

2444

2445 if (SrcType == DestType) {

2446

2447

2448

2449

2450

2451

2452

2453

2454 Kind = CK_NoOp;

2461 }

2463 }

2464

2469 if (!destIsPtr && !srcIsPtr) {

2470

2471

2473 }

2474

2476 assert(srcIsPtr && "One type must be a pointer");

2477

2478

2479

2480 if ((Self.Context.getTypeSize(SrcType) >

2481 Self.Context.getTypeSize(DestType))) {

2482 bool MicrosoftException =

2484 if (MicrosoftException) {

2486 ? diag::warn_void_pointer_to_int_cast

2487 : diag::warn_pointer_to_int_cast;

2488 Self.Diag(OpRange.getBegin(), Diag) << SrcType << DestType << OpRange;

2489 } else {

2490 msg = diag::err_bad_reinterpret_cast_small_int;

2492 }

2493 }

2494 Kind = CK_PointerToIntegral;

2496 }

2497

2499 assert(destIsPtr && "One type must be a pointer");

2501

2502

2503

2504

2505 Kind = CK_IntegralToPointer;

2507 }

2508

2509 if (!destIsPtr || !srcIsPtr) {

2510

2511

2513 }

2514

2515

2519

2520

2521

2523 if (auto CACK =

2525 CStyle))

2527

2529 Kind = CK_AddressSpaceConversion;

2531 if (!CStyle &&

2535 }

2536 } else if (IsLValueCast) {

2537 Kind = CK_LValueBitCast;

2539 Kind = Self.ObjC().PrepareCastToObjCObjectPointer(SrcExpr);

2542 Kind = CK_AnyPointerToBlockPointerCast;

2543 } else {

2544 Kind = CK_BitCast;

2545 }

2546 } else {

2547 Kind = CK_BitCast;

2548 }

2549

2550

2551

2553 return SuccessResult;

2554 }

2555 if (CStyle)

2557

2559

2560

2561

2562

2565

2566

2567 return SuccessResult;

2568 }

2569

2570

2571

2572

2573

2574

2575

2577 Self.getLangOpts().CPlusPlus11 ?

2578 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)

2579 << OpRange;

2580 return SuccessResult;

2581 }

2582

2584

2586 Self.getLangOpts().CPlusPlus11 ?

2587 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)

2588 << OpRange;

2589 return SuccessResult;

2590 }

2591

2592

2599 while (!DestPtee.isNull() && !SrcPtee.isNull()) {

2602 diag::warn_bad_cxx_cast_nested_pointer_addr_space)

2603 << CStyle << SrcType << DestType << SrcExpr.get()->getSourceRange();

2604 break;

2605 }

2608 }

2609

2610

2611

2612

2613

2614

2615 return SuccessResult;

2616}

2617

2619 QualType DestType, bool CStyle,

2620 unsigned &msg, CastKind &Kind) {

2621 if (Self.getLangOpts().OpenCL && Self.getLangOpts().SYCLIsDevice)

2622

2623

2625

2626

2627

2628 auto SrcType = SrcExpr.get()->getType();

2629

2630

2631

2633 if (!SrcPtrType)

2636 if (!DestPtrType)

2638 auto SrcPointeeType = SrcPtrType->getPointeeType();

2639 auto DestPointeeType = DestPtrType->getPointeeType();

2640 if (!DestPointeeType.isAddressSpaceOverlapping(SrcPointeeType,

2641 Self.getASTContext())) {

2642 msg = diag::err_bad_cxx_cast_addr_space_mismatch;

2644 }

2645 auto SrcPointeeTypeWithoutAS =

2646 Self.Context.removeAddrSpaceQualType(SrcPointeeType.getCanonicalType());

2647 auto DestPointeeTypeWithoutAS =

2648 Self.Context.removeAddrSpaceQualType(DestPointeeType.getCanonicalType());

2649 if (Self.Context.hasSameType(SrcPointeeTypeWithoutAS,

2650 DestPointeeTypeWithoutAS)) {

2651 Kind = SrcPointeeType.getAddressSpace() == DestPointeeType.getAddressSpace()

2652 ? CK_NoOp

2653 : CK_AddressSpaceConversion;

2655 } else {

2657 }

2658}

2659

2660void CastOperation::checkAddressSpaceCast(QualType SrcType, QualType DestType) {

2661

2662

2663

2664

2665

2666

2667

2668

2669

2670

2671

2672 if (Self.getLangOpts().OpenCL) {

2673 const Type *DestPtr, *SrcPtr;

2674 bool Nested = false;

2675 unsigned DiagID = diag::err_typecheck_incompatible_address_space;

2676 DestPtr = Self.getASTContext().getCanonicalType(DestType.getTypePtr()),

2677 SrcPtr = Self.getASTContext().getCanonicalType(SrcType.getTypePtr());

2678

2679 while (isa(DestPtr) && isa(SrcPtr)) {

2680 const PointerType *DestPPtr = cast(DestPtr);

2681 const PointerType *SrcPPtr = cast(SrcPtr);

2684 if (Nested

2687 Self.getASTContext())) {

2688 Self.Diag(OpRange.getBegin(), DiagID)

2690 << SrcExpr.get()->getSourceRange();

2691 if (!Nested)

2693 return;

2694 }

2695

2698 Nested = true;

2699 DiagID = diag::ext_nested_pointer_qualifier_mismatch;

2700 }

2701 }

2702}

2703

2705 bool SrcCompatXL = this->getLangOpts().getAltivecSrcCompat() ==

2708

2712 return true;

2713 }

2714 return false;

2715}

2716

2719 bool SrcCompatGCC = this->getLangOpts().getAltivecSrcCompat() ==

2721 if (this->getLangOpts().AltiVec && SrcCompatGCC) {

2723 diag::err_invalid_conversion_between_vector_and_integer)

2724 << VecTy << SrcTy << R;

2725 return true;

2726 }

2727 return false;

2728}

2729

2730void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,

2731 bool ListInitialization) {

2732 assert(Self.getLangOpts().CPlusPlus);

2733

2734

2735 if (isPlaceholder()) {

2736

2737 if (claimPlaceholder(BuiltinType::UnknownAny)) {

2738 SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType,

2739 SrcExpr.get(), Kind,

2740 ValueKind, BasePath);

2741 return;

2742 }

2743

2744 checkNonOverloadPlaceholders();

2745 if (SrcExpr.isInvalid())

2746 return;

2747 }

2748

2749

2750

2751

2753 Kind = CK_ToVoid;

2754

2755 if (claimPlaceholder(BuiltinType::Overload)) {

2756 Self.ResolveAndFixSingleFunctionTemplateSpecialization(

2757 SrcExpr, false,

2758 true, DestRange, DestType,

2759 diag::err_bad_cstyle_cast_overload);

2760 if (SrcExpr.isInvalid())

2761 return;

2762 }

2763

2764 SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());

2765 return;

2766 }

2767

2768

2769 if (DestType->isDependentType() || SrcExpr.get()->isTypeDependent() ||

2770 SrcExpr.get()->isValueDependent()) {

2771 assert(Kind == CK_Dependent);

2772 return;

2773 }

2774

2776 !isPlaceholder(BuiltinType::Overload)) {

2777 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());

2778 if (SrcExpr.isInvalid())

2779 return;

2780 }

2781

2782

2784 if (Self.CheckAltivecInitFromScalar(OpRange, DestType,

2785 SrcExpr.get()->getType())) {

2787 return;

2788 }

2789 if (Self.ShouldSplatAltivecScalarInCast(vecTy) &&

2790 (SrcExpr.get()->getType()->isIntegerType() ||

2791 SrcExpr.get()->getType()->isFloatingType())) {

2792 Kind = CK_VectorSplat;

2793 SrcExpr = Self.prepareVectorSplat(DestType, SrcExpr.get());

2794 return;

2795 }

2796 }

2797

2798

2799 QualType SrcType = SrcExpr.get()->getType();

2801 Self.Diag(OpRange.getBegin(), diag::err_wasm_cast_table)

2802 << 1 << SrcExpr.get()->getSourceRange();

2804 return;

2805 }

2806

2807

2808

2809

2810

2811

2812

2813

2814

2815

2816

2817

2818

2819 unsigned msg = diag::err_bad_cxx_cast_generic;

2821 true, msg);

2822 if (SrcExpr.isInvalid())

2823 return;

2825 Kind = CK_NoOp;

2826

2832 Kind);

2833 if (SrcExpr.isInvalid())

2834 return;

2835

2837

2838

2839 tcr = TryStaticCast(Self, SrcExpr, DestType, CCK, OpRange, msg, Kind,

2840 BasePath, ListInitialization);

2841 if (SrcExpr.isInvalid())

2842 return;

2843

2845

2847 OpRange, msg, Kind);

2848 if (SrcExpr.isInvalid())

2849 return;

2850 }

2851 }

2852 }

2853

2854 if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&

2856 checkObjCConversion(CCK);

2857

2858 if (tcr != TC_Success && msg != 0) {

2859 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {

2861 FunctionDecl *Fn = Self.ResolveAddressOfOverloadedFunction(SrcExpr.get(),

2862 DestType,

2863 true,

2865 if (Fn) {

2866

2867

2868

2870 Self.Diag(OpRange.getBegin(), diag::err_bad_cstyle_cast_overload)

2871 << OE->getName() << DestType << OpRange

2873 Self.NoteAllOverloadCandidates(SrcExpr.get());

2874 }

2875 } else {

2877 OpRange, SrcExpr.get(), DestType, ListInitialization);

2878 }

2879 }

2880

2882 if (Kind == CK_BitCast)

2883 checkCastAlign();

2884

2886 Self.Diag(OpRange.getBegin(), DiagID)

2887 << SrcExpr.get()->getType() << DestType << OpRange;

2888

2889 } else {

2891 }

2892}

2893

2894

2895

2896

2899 if (Self.Diags.isIgnored(diag::warn_bad_function_cast,

2901 return;

2902

2903 if (!isa(SrcExpr.get()))

2904 return;

2905

2908 return;

2911 return;

2915 return;

2917 return;

2919 return;

2921 return;

2923 return;

2925 return;

2926

2928 diag::warn_bad_function_cast)

2930}

2931

2932

2933void CastOperation::CheckCStyleCast() {

2934 assert(Self.getLangOpts().CPlusPlus);

2935

2936

2937 if (claimPlaceholder(BuiltinType::UnknownAny)) {

2938 SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType,

2939 SrcExpr.get(), Kind,

2940 ValueKind, BasePath);

2941 return;

2942 }

2943

2944

2945

2947

2948 SrcExpr = Self.IgnoredValueConversions(SrcExpr.get());

2949 if (SrcExpr.isInvalid())

2950 return;

2951

2952

2953 Kind = CK_ToVoid;

2954 return;

2955 }

2956

2957

2958 if (Self.getASTContext().isDependenceAllowed() &&

2959 (DestType->isDependentType() || SrcExpr.get()->isTypeDependent() ||

2960 SrcExpr.get()->isValueDependent())) {

2961 assert((DestType->containsErrors() || SrcExpr.get()->containsErrors() ||

2962 SrcExpr.get()->containsErrors()) &&

2963 "should only occur in error-recovery path.");

2964 assert(Kind == CK_Dependent);

2965 return;

2966 }

2967

2968

2969 if (SrcExpr.get()->getType() == Self.Context.OverloadTy) {

2971 if (FunctionDecl *FD = Self.ResolveAddressOfOverloadedFunction(

2972 SrcExpr.get(), DestType, true, DAP))

2973 SrcExpr = Self.FixOverloadedFunctionReference(SrcExpr.get(), DAP, FD);

2974 else

2975 return;

2976 assert(SrcExpr.isUsable());

2977 }

2978 SrcExpr = Self.DefaultFunctionArrayLvalueConversion(SrcExpr.get());

2979 if (SrcExpr.isInvalid())

2980 return;

2981 QualType SrcType = SrcExpr.get()->getType();

2982

2984 Self.Diag(OpRange.getBegin(), diag::err_wasm_cast_table)

2985 << 1 << SrcExpr.get()->getSourceRange();

2987 return;

2988 }

2989

2991

2992 checkAddressSpaceCast(SrcType, DestType);

2993 if (SrcExpr.isInvalid())

2994 return;

2995

2996 if (Self.RequireCompleteType(OpRange.getBegin(), DestType,

2997 diag::err_typecheck_cast_to_incomplete)) {

2999 return;

3000 }

3001

3002

3004 Self.Context.hasSameUnqualifiedType(DestType, SrcType)) {

3005 Kind = CK_NoOp;

3006 return;

3007 }

3008

3009

3011 Self.isValidSveBitcast(SrcType, DestType)) {

3012 Kind = CK_BitCast;

3013 return;

3014 }

3015

3016

3018 Self.RISCV().isValidRVVBitcast(SrcType, DestType)) {

3019 Kind = CK_BitCast;

3020 return;

3021 }

3022

3026

3027 if (DestRecordTy && Self.Context.hasSameUnqualifiedType(DestType, SrcType)){

3028

3029 Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_nonscalar)

3030 << DestType << SrcExpr.get()->getSourceRange();

3031 Kind = CK_NoOp;

3032 return;

3033 }

3034

3035

3036 if (DestRecordTy && DestRecordTy->getDecl()->isUnion()) {

3039 Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union)

3040 << SrcExpr.get()->getSourceRange();

3041 Kind = CK_ToUnion;

3042 return;

3043 } else {

3044 Self.Diag(OpRange.getBegin(), diag::err_typecheck_cast_to_union_no_type)

3045 << SrcType << SrcExpr.get()->getSourceRange();

3047 return;

3048 }

3049 }

3050

3051

3052 if (Self.getLangOpts().OpenCL && DestType->isEventT()) {

3054 if (SrcExpr.get()->EvaluateAsInt(Result, Self.Context)) {

3055 llvm::APSInt CastInt = Result.Val.getInt();

3056 if (0 == CastInt) {

3057 Kind = CK_ZeroToOCLOpaqueType;

3058 return;

3059 }

3060 Self.Diag(OpRange.getBegin(),

3061 diag::err_opencl_cast_non_zero_to_event_t)

3062 << toString(CastInt, 10) << SrcExpr.get()->getSourceRange();

3064 return;

3065 }

3066 }

3067

3068

3069 Self.Diag(OpRange.getBegin(), diag::err_typecheck_cond_expect_scalar)

3070 << DestType << SrcExpr.get()->getSourceRange();

3072 return;

3073 }

3074

3075

3076

3077

3080 Self.Diag(SrcExpr.get()->getExprLoc(),

3081 diag::err_typecheck_expect_scalar_operand)

3082 << SrcType << SrcExpr.get()->getSourceRange();

3084 return;

3085 }

3086

3087

3088

3089

3090

3092

3093

3094

3097 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)

3098 << 0 << DestType;

3100 return;

3101 }

3103

3104

3108 Self.CurFPFeatureOverrides());

3109 }

3110 }

3112 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_nullptr_cast)

3113 << 1 << SrcType;

3115 return;

3116 }

3117

3119 SrcExpr = Self.CheckExtVectorCast(OpRange, DestType, SrcExpr.get(), Kind);

3120 return;

3121 }

3122

3124 if (Self.CheckMatrixCast(OpRange, DestType, SrcType, Kind))

3126 return;

3127 }

3128

3130 if (Self.CheckAltivecInitFromScalar(OpRange, DestType, SrcType)) {

3132 return;

3133 }

3134 if (Self.ShouldSplatAltivecScalarInCast(DestVecTy) &&

3136 Kind = CK_VectorSplat;

3137 SrcExpr = Self.prepareVectorSplat(DestType, SrcExpr.get());

3138 } else if (Self.CheckVectorCast(OpRange, DestType, SrcType, Kind)) {

3140 }

3141 return;

3142 }

3143

3145 if (Self.CheckVectorCast(OpRange, SrcType, DestType, Kind))

3147 return;

3148 }

3149

3150

3151

3152

3153

3154

3155 if (isa(SrcExpr.get())) {

3156 Self.Diag(SrcExpr.get()->getExprLoc(), diag::err_cast_selector_expr);

3158 return;

3159 }

3160

3161

3162

3165 Self.Diag(SrcExpr.get()->getExprLoc(),

3166 diag::err_cast_pointer_from_non_pointer_int)

3167 << SrcType << SrcExpr.get()->getSourceRange();

3169 return;

3170 }

3176 Self.Diag(SrcExpr.get()->getBeginLoc(),

3177 diag::err_cast_pointer_to_non_pointer_int)

3178 << DestType << SrcExpr.get()->getSourceRange();

3180 return;

3181 }

3182

3183 if ((Self.Context.getTypeSize(SrcType) >

3184 Self.Context.getTypeSize(DestType)) &&

3186

3187

3188

3189

3190

3191 unsigned Diag;

3193 Diag = DestType->isEnumeralType() ? diag::warn_void_pointer_to_enum_cast

3194 : diag::warn_void_pointer_to_int_cast;

3196 Diag = diag::warn_pointer_to_enum_cast;

3197 else

3198 Diag = diag::warn_pointer_to_int_cast;

3199 Self.Diag(OpRange.getBegin(), Diag) << SrcType << DestType << OpRange;

3200 }

3201 }

3202

3203 if (Self.getLangOpts().OpenCL && Self.getOpenCLOptions().isAvailableOption(

3204 "cl_khr_fp16", Self.getLangOpts())) {

3206 Self.Diag(SrcExpr.get()->getBeginLoc(), diag::err_opencl_cast_to_half)

3207 << DestType << SrcExpr.get()->getSourceRange();

3209 return;

3210 }

3211 }

3212

3213

3214 if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers()) {

3216 if (SrcExpr.isInvalid())

3217 return;

3218

3220 if (Self.getLangOpts().ObjCAutoRefCount && CastPtr) {

3223 Qualifiers ExprQuals = ExprPtr->getPointeeType().getQualifiers();

3225 ExprPtr->getPointeeType()->isObjCLifetimeType() &&

3227 Self.Diag(SrcExpr.get()->getBeginLoc(),

3228 diag::err_typecheck_incompatible_ownership)

3230 << SrcExpr.get()->getSourceRange();

3231 return;

3232 }

3233 }

3234 } else if (Self.ObjC().CheckObjCARCUnavailableWeakConversion(DestType,

3235 SrcType)) {

3236 Self.Diag(SrcExpr.get()->getBeginLoc(),

3237 diag::err_arc_convesion_of_weak_unavailable)

3238 << 1 << SrcType << DestType << SrcExpr.get()->getSourceRange();

3240 return;

3241 }

3242 }

3243

3245 Self.Diag(OpRange.getBegin(), DiagID) << SrcType << DestType << OpRange;

3246

3247 if (isa(SrcType) && isa(DestType)) {

3250

3253

3254 if (SrcRD && DestRD && SrcRD->hasAttr() &&

3255 SrcRD != DestRD) {

3256

3257 Self.Diag(OpRange.getBegin(), diag::err_cast_from_randomized_struct)

3258 << SrcType << DestType;

3260 return;

3261 }

3262 }

3263

3267 Kind = Self.PrepareScalarCast(SrcExpr, DestType);

3268 if (SrcExpr.isInvalid())

3269 return;

3270

3271 if (Kind == CK_BitCast)

3272 checkCastAlign();

3273}

3274

3275void CastOperation::CheckBuiltinBitCast() {

3276 QualType SrcType = SrcExpr.get()->getType();

3277

3278 if (Self.RequireCompleteType(OpRange.getBegin(), DestType,

3279 diag::err_typecheck_cast_to_incomplete) ||

3280 Self.RequireCompleteType(OpRange.getBegin(), SrcType,

3281 diag::err_incomplete_type)) {

3283 return;

3284 }

3285

3286 if (SrcExpr.get()->isPRValue())

3287 SrcExpr = Self.CreateMaterializeTemporaryExpr(SrcType, SrcExpr.get(),

3288 false);

3289

3290 CharUnits DestSize = Self.Context.getTypeSizeInChars(DestType);

3291 CharUnits SourceSize = Self.Context.getTypeSizeInChars(SrcType);

3292 if (DestSize != SourceSize) {

3293 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_type_size_mismatch)

3294 << SrcType << DestType << (int)SourceSize.getQuantity()

3297 return;

3298 }

3299

3301 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable)

3302 << 1;

3304 return;

3305 }

3306

3308 Self.Diag(OpRange.getBegin(), diag::err_bit_cast_non_trivially_copyable)

3309 << 0;

3311 return;

3312 }

3313

3314 Kind = CK_LValueToRValueBitCast;

3315}

3316

3317

3318

3322 return;

3323

3327 return;

3328

3329 QualType TheOffendingSrcType, TheOffendingDestType;

3332 &TheOffendingSrcType, &TheOffendingDestType,

3333 &CastAwayQualifiers) !=

3334 CastAwayConstnessKind::CACK_Similar)

3335 return;

3336

3337

3338 int qualifiers = -1;

3339 if (CastAwayQualifiers.hasConst() && CastAwayQualifiers.hasVolatile()) {

3340 qualifiers = 0;

3341 } else if (CastAwayQualifiers.hasConst()) {

3342 qualifiers = 1;

3343 } else if (CastAwayQualifiers.hasVolatile()) {

3344 qualifiers = 2;

3345 }

3346

3347 if (qualifiers == -1)

3349 << SrcType << DestType;

3350 else

3352 << TheOffendingSrcType << TheOffendingDestType << qualifiers;

3353}

3354

3359 CastOperation Op(*this, CastTypeInfo->getType(), CastExpr);

3362

3364 Op.CheckCXXCStyleCast( false,

3365 isa(CastExpr));

3366 } else {

3367 Op.CheckCStyleCast();

3368 }

3369

3370 if (Op.SrcExpr.isInvalid())

3372

3373

3375

3377 Context, Op.ResultType, Op.ValueKind, Op.Kind, Op.SrcExpr.get(),

3379}

3380

3386 assert(LPLoc.isValid() && "List-initialization shouldn't get here.");

3389 Op.OpRange = SourceRange(Op.DestRange.getBegin(), RPLoc);

3390

3391 Op.CheckCXXCStyleCast(true, false);

3392 if (Op.SrcExpr.isInvalid())

3394

3395 auto *SubExpr = Op.SrcExpr.get();

3396 if (auto *BindExpr = dyn_cast(SubExpr))

3397 SubExpr = BindExpr->getSubExpr();

3398 if (auto *ConstructExpr = dyn_cast(SubExpr))

3399 ConstructExpr->setParenOrBraceRange(SourceRange(LPLoc, RPLoc));

3400

3401

3403

3405 Context, Op.ResultType, Op.ValueKind, CastTypeInfo, Op.Kind,

3407}

Defines the clang::ASTContext interface.

Defines the clang::Expr interface and subclasses for C++ expressions.

static DiagnosticBuilder Diag(DiagnosticsEngine *Diags, const LangOptions &Features, FullSourceLoc TokLoc, const char *TokBegin, const char *TokRangeBegin, const char *TokRangeEnd, unsigned DiagID)

Produce a diagnostic highlighting some portion of a literal.

Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.

Defines the clang::Preprocessor interface.

static std::string toString(const clang::SanitizerSet &Sanitizers)

Produce a string containing comma-separated names of sanitizers in Sanitizers set.

static void DiagnoseReinterpretUpDownCast(Sema &Self, const Expr *SrcExpr, QualType DestType, SourceRange OpRange)

Check that a reinterpret_cast(SrcExpr) is not used as upcast or downcast between respective...

static CastAwayConstnessKind CastsAwayConstness(Sema &Self, QualType SrcType, QualType DestType, bool CheckCVR, bool CheckObjCLifetime, QualType *TheOffendingSrcType=nullptr, QualType *TheOffendingDestType=nullptr, Qualifiers *CastAwayQualifiers=nullptr)

Check if the pointer conversion from SrcType to DestType casts away constness as defined in C++ [expr...

static TryCastResult getCastAwayConstnessCastKind(CastAwayConstnessKind CACK, unsigned &DiagID)

static bool IsAddressSpaceConversion(QualType SrcType, QualType DestType)

@ CT_Reinterpret

reinterpret_cast

@ CT_Functional

Type(expr)

@ CT_Addrspace

addrspace_cast

static TryCastResult TryConstCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, unsigned &msg)

TryConstCast - See if a const_cast from source to destination is allowed, and perform it if it is.

static bool isValidCast(TryCastResult TCR)

static void diagnoseBadCast(Sema &S, unsigned msg, CastType castType, SourceRange opRange, Expr *src, QualType destType, bool listInitialization)

Diagnose a failed cast.

static bool tryDiagnoseOverloadedCast(Sema &S, CastType CT, SourceRange range, Expr *src, QualType destType, bool listInitialization)

Try to diagnose a failed overloaded cast.

static bool argTypeIsABIEquivalent(QualType SrcType, QualType DestType, ASTContext &Context)

static unsigned int checkCastFunctionType(Sema &Self, const ExprResult &SrcExpr, QualType DestType)

@ TC_Success

The cast method is appropriate and successful.

@ TC_Extension

The cast method is appropriate and accepted as a language extension.

@ TC_Failed

The cast method is appropriate, but failed.

@ TC_NotApplicable

The cast method is not applicable.

static TryCastResult TryStaticReferenceDowncast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, SourceRange OpRange, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)

Tests whether a conversion according to C++ 5.2.9p5 is valid.

static void DiagnoseCastQual(Sema &Self, const ExprResult &SrcExpr, QualType DestType)

DiagnoseCastQual - Warn whenever casts discards a qualifiers, be it either const, volatile or both.

static TryCastResult TryStaticImplicitCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, CheckedConversionKind CCK, SourceRange OpRange, unsigned &msg, CastKind &Kind, bool ListInitialization)

TryStaticImplicitCast - Tests whether a conversion according to C++ 5.2.9p2 is valid:

static void DiagnoseCastOfObjCSEL(Sema &Self, const ExprResult &SrcExpr, QualType DestType)

static void DiagnoseBadFunctionCast(Sema &Self, const ExprResult &SrcExpr, QualType DestType)

DiagnoseBadFunctionCast - Warn whenever a function call is cast to a non-matching type.

static TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, bool CStyle, SourceRange OpRange, QualType OrigSrcType, QualType OrigDestType, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)

TryStaticDowncast - Common functionality of TryStaticReferenceDowncast and TryStaticPointerDowncast.

static TryCastResult TryReinterpretCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, SourceRange OpRange, unsigned &msg, CastKind &Kind)

static bool fixOverloadedReinterpretCastExpr(Sema &Self, QualType DestType, ExprResult &Result)

static CastAwayConstnessKind unwrapCastAwayConstnessLevel(ASTContext &Context, QualType &T1, QualType &T2)

Unwrap one level of types for CastsAwayConstness.

static void DiagnoseCallingConvCast(Sema &Self, const ExprResult &SrcExpr, QualType DstType, SourceRange OpRange)

Diagnose casts that change the calling convention of a pointer to a function defined in the current T...

static TryCastResult TryLValueToRValueCast(Sema &Self, Expr *SrcExpr, QualType DestType, bool CStyle, CastKind &Kind, CXXCastPath &BasePath, unsigned &msg)

Tests whether a conversion according to N2844 is valid.

static TryCastResult TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr, QualType SrcType, QualType DestType, bool CStyle, SourceRange OpRange, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)

TryStaticMemberPointerUpcast - Tests whether a conversion according to C++ 5.2.9p9 is valid:

static void checkIntToPointerCast(bool CStyle, const SourceRange &OpRange, const Expr *SrcExpr, QualType DestType, Sema &Self)

static TryCastResult TryAddressSpaceCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, bool CStyle, unsigned &msg, CastKind &Kind)

static TryCastResult TryStaticPointerDowncast(Sema &Self, QualType SrcType, QualType DestType, bool CStyle, SourceRange OpRange, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)

Tests whether a conversion according to C++ 5.2.9p8 is valid.

static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr, QualType DestType, CheckedConversionKind CCK, SourceRange OpRange, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath, bool ListInitialization)

TryStaticCast - Check if a static cast can be performed, and do so if possible.

This file declares semantic analysis for Objective-C.

This file declares semantic analysis functions specific to RISC-V.

static QualType getPointeeType(const MemRegion *R)

TextDiagnosticBuffer::DiagList DiagList

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

const LangOptions & getLangOpts() const

bool hasSameUnqualifiedType(QualType T1, QualType T2) const

Determine whether the given types are equivalent after cvr-qualifiers have been removed.

const ArrayType * getAsArrayType(QualType T) const

Type Query functions.

uint64_t getTypeSize(QualType T) const

Return the size of the specified (complete) type T, in bits.

CharUnits getTypeSizeInChars(QualType T) const

Return the size of the specified (complete) type T, in characters.

void UnwrapSimilarArrayTypes(QualType &T1, QualType &T2, bool AllowPiMismatch=true) const

Attempt to unwrap two types that may both be array types with the same bound (or both be array types ...

bool UnwrapSimilarTypes(QualType &T1, QualType &T2, bool AllowPiMismatch=true) const

Attempt to unwrap two types that may be similar (C++ [conv.qual]).

ASTRecordLayout - This class contains layout information for one RecordDecl, which is a struct/union/...

CharUnits getBaseClassOffset(const CXXRecordDecl *Base) const

getBaseClassOffset - Get the offset, in chars, for the given base class.

Represents a C++2a __builtin_bit_cast(T, v) expression.

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

static CStyleCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *BasePath, FPOptionsOverride FPO, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation R)

static CXXAddrspaceCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)

Represents a path from a specific derived class (which is not represented as part of the path) to a p...

BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...

std::list< CXXBasePath >::const_iterator const_paths_iterator

static CXXConstCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, Expr *Op, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)

static CXXDynamicCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)

static CXXFunctionalCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, TypeSourceInfo *Written, CastKind Kind, Expr *Op, const CXXCastPath *Path, FPOptionsOverride FPO, SourceLocation LPLoc, SourceLocation RPLoc)

Represents a static or instance method of a struct/union/class.

const CXXRecordDecl * getParent() const

Return the parent of this method declaration, which is the class in which this method is defined.

Represents a C++ struct/union/class.

bool isDerivedFrom(const CXXRecordDecl *Base) const

Determine whether this class is derived from the class Base.

static CXXReinterpretCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind Kind, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *WrittenTy, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)

static CXXStaticCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, CastKind K, Expr *Op, const CXXCastPath *Path, TypeSourceInfo *Written, FPOptionsOverride FPO, SourceLocation L, SourceLocation RParenLoc, SourceRange AngleBrackets)

bool isAtLeastAsQualifiedAs(CanQual< T > Other, const ASTContext &Ctx) const

Determines whether this canonical type is at least as qualified as the Other canonical type.

CanQual< T > getUnqualifiedType() const

Retrieve the unqualified form of this type.

CanProxy< U > getAs() const

Retrieve a canonical type pointer with a different static type, upcasting or downcasting as needed.

CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...

static const FieldDecl * getTargetFieldForToUnionCast(QualType unionType, QualType opType)

CharUnits - This is an opaque type for sizes expressed in character units.

QuantityType getQuantity() const

getQuantity - Get the raw integer representation of this quantity.

static CharUnits Zero()

Zero - Construct a CharUnits quantity of zero.

A POD class for pairing a NamedDecl* with an access specifier.

bool isInvalidDecl() const

Information about one declarator, including the parsed type information and the identifier.

bool isIgnored(unsigned DiagID, SourceLocation Loc) const

Determine whether the diagnostic is known to be ignored.

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

This represents one expression.

bool isTypeDependent() const

Determines whether the type of this expression depends on.

Expr * IgnoreParenImpCasts() LLVM_READONLY

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

bool isLValue() const

isLValue - True if this expression is an "l-value" according to the rules of the current language.

ExprObjectKind getObjectKind() const

getObjectKind - The object kind that this expression produces.

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

SourceLocation getExprLoc() const LLVM_READONLY

getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...

bool refersToBitField() const

Returns true if this expression is a gl-value that potentially refers to a bit-field.

static ExprValueKind getValueKindForType(QualType T)

getValueKindForType - Given a formal return or parameter type, give its value kind.

static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)

Create a code modification hint that replaces the given source range with the given code string.

static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)

Create a code modification hint that inserts the given code string at a specific location.

Represents a function declaration or definition.

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

FunctionType - C99 6.7.5.3 - Function Declarators.

static StringRef getNameForCallConv(CallingConv CC)

CallingConv getCallConv() const

QualType getReturnType() const

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

tok::TokenKind getTokenID() const

If this is a source-language token (e.g.

bool isKeyword(const LangOptions &LangOpts) const

Return true if this token is a keyword in the specified language.

static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)

Describes the kind of initialization being performed, along with location information for tokens rela...

static InitializationKind CreateCast(SourceRange TypeRange)

Create a direct initialization due to a cast that isn't a C-style or functional cast.

static InitializationKind CreateFunctionalCast(SourceRange TypeRange, bool InitList)

Create a direct initialization for a functional cast.

static InitializationKind CreateCStyleCast(SourceLocation StartLoc, SourceRange TypeRange, bool InitList)

Create a direct initialization for a C-style cast.

Describes the sequence of initializations required to initialize a given object or reference with a s...

ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)

Perform the actual initialization of the given entity based on the computed initialization sequence.

FailureKind getFailureKind() const

Determine why initialization failed.

OverloadingResult getFailedOverloadResult() const

Get the overloading result, for when the initialization sequence failed due to a bad overload.

bool Failed() const

Determine whether the initialization sequence is invalid.

@ FK_UserConversionOverloadFailed

Overloading for a user-defined conversion failed.

@ FK_ConstructorOverloadFailed

Overloading for initialization by constructor failed.

@ FK_ParenthesizedListInitFailed

Parenthesized list initialization failed at some point.

bool isConstructorInitialization() const

Determine whether this initialization is direct call to a constructor.

OverloadCandidateSet & getFailedCandidateSet()

Retrieve a reference to the candidate set when overload resolution fails.

Describes an entity that is being initialized.

static InitializedEntity InitializeTemporary(QualType Type)

Create the initialization entity for a temporary.

Represents a matrix type, as defined in the Matrix Types clang extensions.

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

QualType getPointeeType() const

bool isMemberFunctionPointer() const

Returns true if the member type (i.e.

const Type * getClass() const

SourceRange getSourceRange() const LLVM_READONLY

Retrieve the source range covering the entirety of this nested-name-specifier.

OverloadCandidateSet - A set of overload candidates, used in C++ overload resolution (C++ 13....

SmallVectorImpl< OverloadCandidate >::iterator iterator

void NoteCandidates(PartialDiagnosticAt PA, Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef< Expr * > Args, StringRef Opc="", SourceLocation Loc=SourceLocation(), llvm::function_ref< bool(OverloadCandidate &)> Filter=[](OverloadCandidate &) { return true;})

When overload resolution fails, prints diagnostic messages containing the candidates in the candidate...

OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc, OverloadCandidateSet::iterator &Best)

Find the best viable function on this overload set, if it exists.

A reference to an overloaded function set, either an UnresolvedLookupExpr or an UnresolvedMemberExpr.

static FindResult find(Expr *E)

Finds the overloaded expression in the given expression E of OverloadTy.

NestedNameSpecifierLoc getQualifierLoc() const

Fetches the nested-name qualifier with source-location information, if one was given.

DeclarationName getName() const

Gets the name looked up.

PointerType - C99 6.7.5.1 - Pointer Declarators.

QualType getPointeeType() const

Engages in a tight little dance with the lexer to efficiently preprocess tokens.

IdentifierInfo * getIdentifierInfo(StringRef Name) const

Return information about the specified preprocessor identifier token.

StringRef getLastMacroWithSpelling(SourceLocation Loc, ArrayRef< TokenValue > Tokens) const

Return the name of the macro defined before Loc that has spelling Tokens.

A (possibly-)qualified type.

bool isTriviallyCopyableType(const ASTContext &Context) const

Return true if this is a trivially copyable type (C++0x [basic.types]p9)

QualType getNonLValueExprType(const ASTContext &Context) const

Determine the type of a (typically non-lvalue) expression with the specified result type.

bool isAddressSpaceOverlapping(QualType T, const ASTContext &Ctx) const

Returns true if address space qualifiers overlap with T address space qualifiers.

bool isNull() const

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

const Type * getTypePtr() const

Retrieves a pointer to the underlying (unqualified) type.

LangAS getAddressSpace() const

Return the address space of this type.

Qualifiers getQualifiers() const

Retrieve the set of qualifiers applied to this type.

QualType getNonReferenceType() const

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

QualType getUnqualifiedType() const

Retrieve the unqualified variant of the given type, removing as little sugar as possible.

QualType withCVRQualifiers(unsigned CVR) const

unsigned getCVRQualifiers() const

Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.

static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)

bool isAtLeastAsQualifiedAs(QualType Other, const ASTContext &Ctx) const

Determine whether this type is at least as qualified as the other given type, requiring exact equalit...

The collection of all-type qualifiers we support.

unsigned getCVRQualifiers() const

void removeObjCLifetime()

bool compatiblyIncludes(Qualifiers other, const ASTContext &Ctx) const

Determines if these qualifiers compatibly include another set.

static bool isAddressSpaceSupersetOf(LangAS A, LangAS B, const ASTContext &Ctx)

Returns true if address space A is equal to or a superset of B.

static Qualifiers fromCVRMask(unsigned CVR)

bool compatiblyIncludesObjCLifetime(Qualifiers other) const

Determines if these qualifiers compatibly include another set of qualifiers from the narrow perspecti...

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

Represents a struct/union/class.

RecordDecl * getDefinition() const

Returns the RecordDecl that actually defines this struct/union/class.

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

RecordDecl * getDecl() const

Base for LValueReferenceType and RValueReferenceType.

QualType getPointeeType() const

SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)

Emit a diagnostic.

PartialDiagnostic PDiag(unsigned DiagID=0)

Build a partial diagnostic.

Sema - This implements semantic analysis and AST building for C.

ReferenceCompareResult

ReferenceCompareResult - Expresses the result of comparing two types (cv1 T1 and cv2 T2) to determine...

@ Ref_Incompatible

Ref_Incompatible - The two types are incompatible, so direct reference binding is not possible.

@ Ref_Compatible

Ref_Compatible - The two types are reference-compatible.

ExprResult BuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, QualType Type, SourceLocation LParenLoc, Expr *CastExpr, SourceLocation RParenLoc)

ExprResult BuildBuiltinBitCastExpr(SourceLocation KWLoc, TypeSourceInfo *TSI, Expr *Operand, SourceLocation RParenLoc)

FPOptionsOverride CurFPFeatureOverrides()

bool ShouldSplatAltivecScalarInCast(const VectorType *VecTy)

ExprResult ActOnBuiltinBitCastExpr(SourceLocation KWLoc, Declarator &Dcl, ExprResult Operand, SourceLocation RParenLoc)

const LangOptions & getLangOpts() const

void CheckExtraCXXDefaultArguments(Declarator &D)

CheckExtraCXXDefaultArguments - Check for any extra default arguments in the declarator,...

ExprResult BuildCStyleCastExpr(SourceLocation LParenLoc, TypeSourceInfo *Ty, SourceLocation RParenLoc, Expr *Op)

ExprResult ActOnCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, SourceLocation LAngleBracketLoc, Declarator &D, SourceLocation RAngleBracketLoc, SourceLocation LParenLoc, Expr *E, SourceLocation RParenLoc)

ActOnCXXNamedCast - Parse {dynamic,static,reinterpret,const,addrspace}_cast's.

void DiscardMisalignedMemberAddress(const Type *T, Expr *E)

This function checks if the expression is in the sef of potentially misaligned members and it is conv...

void CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType, bool IsDereference, SourceRange Range)

TypeSourceInfo * GetTypeForDeclaratorCast(Declarator &D, QualType FromTy)

DiagnosticsEngine & Diags

ExprResult BuildCXXNamedCast(SourceLocation OpLoc, tok::TokenKind Kind, TypeSourceInfo *Ty, Expr *E, SourceRange AngleBrackets, SourceRange Parens)

bool CheckAltivecInitFromScalar(SourceRange R, QualType VecTy, QualType SrcTy)

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

A trivial tuple used to represent a source range.

SourceLocation getBegin() const

SourceLocation getEndLoc() const LLVM_READONLY

SourceRange getSourceRange() const LLVM_READONLY

SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...

SourceLocation getBeginLoc() const LLVM_READONLY

StringLiteral - This represents a string literal expression, e.g.

StringRef getString() const

bool isCompleteDefinition() const

Return true if this decl has its body fully specified.

Stores token information for comparing actual tokens with predefined values.

Base wrapper for a particular "section" of type source info.

SourceRange getSourceRange() const LLVM_READONLY

Get the full source range.

SourceLocation getEndLoc() const

Get the end source location.

SourceLocation getBeginLoc() const

Get the begin source location.

A container of type source information.

TypeLoc getTypeLoc() const

Return the TypeLoc wrapper for the type source info.

QualType getType() const

Return the type wrapped by this type source info.

The base class of the type hierarchy.

bool isIncompleteOrObjectType() const

Return true if this is an incomplete or object type, in other words, not a function type.

CXXRecordDecl * getAsCXXRecordDecl() const

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

bool isBlockPointerType() const

bool isBooleanType() const

bool isFunctionReferenceType() const

bool isIncompleteArrayType() const

bool isPlaceholderType() const

Test for a type which does not represent an actual type-system type but is instead used as a placehol...

bool isSignedIntegerType() const

Return true if this is an integer type that is signed, according to C99 6.2.5p4 [char,...

bool isComplexType() const

isComplexType() does not include complex integers (a GCC extension).

bool isRValueReferenceType() const

bool isConstantArrayType() const

bool isVoidPointerType() const

bool isFunctionPointerType() const

bool isArithmeticType() const

bool isPointerType() const

bool isIntegerType() const

isIntegerType() does not include complex integers (a GCC extension).

const T * castAs() const

Member-template castAs.

bool isReferenceType() const

bool isEnumeralType() const

bool isScalarType() const

const CXXRecordDecl * getPointeeCXXRecordDecl() const

If this is a pointer or reference to a RecordType, return the CXXRecordDecl that the type refers to.

bool isSizelessBuiltinType() const

bool isIntegralType(const ASTContext &Ctx) const

Determine whether this type is an integral type.

QualType getPointeeType() const

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

bool isIntegralOrEnumerationType() const

Determine whether this type is an integral or enumeration type.

bool isExtVectorType() const

bool isAnyCharacterType() const

Determine whether this type is any of the built-in character types.

bool isLValueReferenceType() const

bool isDependentType() const

Whether this type is a dependent type, meaning that its definition somehow depends on a template para...

bool isFixedPointType() const

Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.

const BuiltinType * getAsPlaceholderType() const

bool isWebAssemblyTableType() const

Returns true if this is a WebAssembly table type: either an array of reference types,...

bool containsErrors() const

Whether this type is an error type.

bool isMemberPointerType() const

bool isMatrixType() const

bool isComplexIntegerType() const

bool isObjCObjectType() const

bool isObjCLifetimeType() const

Returns true if objects of this type have lifetime semantics under ARC.

bool isFunctionType() const

bool isObjCObjectPointerType() const

bool isMemberFunctionPointerType() const

bool isVectorType() const

bool isRealFloatingType() const

Floating point categories.

bool isFloatingType() const

bool isUnsignedIntegerType() const

Return true if this is an integer type that is unsigned, according to C99 6.2.5p6 [which returns true...

bool isAnyPointerType() const

const T * getAs() const

Member-template getAs'.

bool isNullPtrType() const

bool isRecordType() const

bool isFunctionNoProtoType() const

RecordDecl * getAsRecordDecl() const

Retrieves the RecordDecl this type refers to.

Represents a GCC generic vector type.

VectorKind getVectorKind() const

Defines the clang::TargetInfo interface.

const internal::VariadicDynCastAllOfMatcher< Stmt, CastExpr > castExpr

Matches any cast nodes of Clang's AST.

TokenKind

Provides a simple uniform namespace for tokens from all C languages.

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

OverloadingResult

OverloadingResult - Capture the result of performing overload resolution.

@ OR_Deleted

Succeeded, but refers to a deleted function.

@ OR_Success

Overload resolution succeeded.

@ OR_Ambiguous

Ambiguous candidates found.

@ OR_No_Viable_Function

No viable function found.

OverloadCandidateDisplayKind

@ OCD_AmbiguousCandidates

Requests that only tied-for-best candidates be shown.

@ OCD_ViableCandidates

Requests that only viable candidates be shown.

@ OCD_AllCandidates

Requests that all candidates be shown.

@ OK_VectorComponent

A vector component is an element or range of elements on a vector.

@ OK_ObjCProperty

An Objective-C property is a logical field of an Objective-C object which is read and written via Obj...

@ OK_ObjCSubscript

An Objective-C array/dictionary subscripting which reads an object or writes at the subscripted array...

@ OK_Ordinary

An ordinary object is located at an address in memory.

@ OK_BitField

A bitfield object is a bitfield on a C or C++ record.

@ OK_MatrixComponent

A matrix component is a single element of a matrix.

@ Self

'self' clause, allowed on Compute and Combined Constructs, plus 'update'.

@ Result

The result type of a method or function.

CastKind

CastKind - The kind of operation required for a conversion.

ExprValueKind

The categorization of expression values, currently following the C++11 scheme.

@ VK_PRValue

A pr-value expression (in the C++11 taxonomy) produces a temporary value.

const FunctionProtoType * T

std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt

A partial diagnostic along with the source location where this diagnostic occurs.

CallingConv

CallingConv - Specifies the calling convention that a function uses.

@ AltiVecBool

is AltiVec 'vector bool ...'

@ AltiVecVector

is AltiVec vector

@ AltiVecPixel

is AltiVec 'vector Pixel'

@ None

The alignment was not explicit in code.

@ Class

The "class" keyword introduces the elaborated-type-specifier.

@ Enum

The "enum" keyword introduces the elaborated-type-specifier.

@ Parens

New-expression has a C++98 paren-delimited initializer.

CheckedConversionKind

The kind of conversion being performed.

@ CStyleCast

A C-style cast.

@ OtherCast

A cast other than a C-style cast.

@ FunctionalCast

A functional-style cast.

Represents an element in a path from a derived class to a base class.

EvalResult is a struct with detailed info about an evaluated expression.

OverloadExpr * Expression

ReferenceConversions

The conversions that would be performed on an lvalue of type T2 when binding a reference of type T1 t...