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

1

2

3

4

5

6

7

8

9

10

11

12

13

14

15

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

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

31#include

32using namespace clang;

33

34

35

44

48

58

59namespace {

60 struct CastOperation {

61 CastOperation(Sema &S, QualType destType, ExprResult src)

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

65 Kind(CK_Dependent), IsARCUnbridgedCast(false) {

66

67

68

69

70

71

72

73

74

75

76

77

79 !DestType->isArrayType() && !DestType.getPointerAuth()) {

80 DestType = DestType.getAtomicUnqualifiedType();

81 }

82

83 if (const BuiltinType *placeholder =

85 PlaceholderKind = placeholder->getKind();

86 } else {

88 }

89 }

90

91 Sema &Self;

93 QualType DestType;

94 QualType ResultType;

99 bool IsARCUnbridgedCast;

100

101 struct OpRangeType {

102 SourceLocation Locations[3];

103

104 OpRangeType(SourceLocation Begin, SourceLocation LParen,

105 SourceLocation RParen)

106 : Locations{Begin, LParen, RParen} {}

107

108 OpRangeType() = default;

109

110 SourceLocation getBegin() const { return Locations[0]; }

111

112 SourceLocation getLParenLoc() const { return Locations[1]; }

113

114 SourceLocation getRParenLoc() const { return Locations[2]; }

115

116 friend const StreamingDiagnostic &

117 operator<<(const StreamingDiagnostic &DB, OpRangeType Op) {

118 return DB << SourceRange(Op);

119 }

120

121 SourceRange getParenRange() const {

122 return SourceRange(getLParenLoc(), getRParenLoc());

123 }

124

125 operator SourceRange() const {

126 return SourceRange(getBegin(), getRParenLoc());

127 }

128 };

129

130 OpRangeType OpRange;

131 SourceRange DestRange;

132

133

134 void CheckConstCast();

135 void CheckReinterpretCast();

136 void CheckStaticCast();

137 void CheckDynamicCast();

138 void CheckCXXCStyleCast(bool FunctionalCast, bool ListInitialization);

140 void CheckCStyleCast();

141 void CheckBuiltinBitCast();

142 void CheckAddrspaceCast();

143

144 void updatePartOfExplicitCastFlags(CastExpr *CE) {

145

146

147

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

149 ICE->setIsPartOfExplicitCast(true);

150 }

151

152

153

155

156

157 if (IsARCUnbridgedCast) {

159 Self.Context, Self.Context.ARCUnbridgedCastTy, CK_Dependent,

161 Self.CurFPFeatureOverrides());

162 }

163 updatePartOfExplicitCastFlags(castExpr);

165 }

166

167

168

169

170

171

173 if (PlaceholderKind != K) return false;

174

176 return true;

177 }

178

179 bool isPlaceholder() const {

180 return PlaceholderKind != 0;

181 }

183 return PlaceholderKind == K;

184 }

185

186

187 void checkAddressSpaceCast(QualType SrcType, QualType DestType);

188

189 void checkCastAlign() {

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

191 }

192

194 bool IsReinterpretCast = false) {

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

196

197 Expr *src = SrcExpr.get();

198 if (Self.ObjC().CheckObjCConversion(

199 OpRange, DestType, src, CCK, true, false, BO_PtrMemD,

201 IsARCUnbridgedCast = true;

202 SrcExpr = src;

203 }

204

205 void checkQualifiedDestType() {

206

207 if (DestType.getPointerAuth()) {

208 Self.Diag(DestRange.getBegin(), diag::err_ptrauth_qualifier_cast)

209 << DestType << DestRange;

210 }

211 }

212

213

214 void checkNonOverloadPlaceholders() {

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

216 return;

217

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

219 if (SrcExpr.isInvalid())

220 return;

222 }

223 };

224

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

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

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

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

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

232 }

233 }

234 }

235 }

236 }

237

238 struct CheckNoDerefRAII {

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

240 ~CheckNoDerefRAII() {

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

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

243 Op.OpRange.getBegin());

244 }

245

246 CastOperation &Op;

247 };

248}

249

252

253

254

255

256

257

258

259

260

261

262

263

265 QualType DestType, bool CStyle,

268 unsigned &msg);

271 bool CStyle, CastOperation::OpRangeType OpRange,

272 unsigned &msg, CastKind &Kind,

276 bool CStyle, CastOperation::OpRangeType OpRange,

280 CastOperation::OpRangeType OpRange,

282 QualType OrigDestType, unsigned &msg,

286 QualType DestType, bool CStyle,

287 CastOperation::OpRangeType OpRange, unsigned &msg,

289

293 CastOperation::OpRangeType OpRange,

294 unsigned &msg, CastKind &Kind,

295 bool ListInitialization);

298 CastOperation::OpRangeType OpRange,

299 unsigned &msg, CastKind &Kind,

301 bool ListInitialization);

303 QualType DestType, bool CStyle,

304 unsigned &msg);

306 QualType DestType, bool CStyle,

307 CastOperation::OpRangeType OpRange,

308 unsigned &msg, CastKind &Kind);

310 QualType DestType, bool CStyle,

311 unsigned &msg, CastKind &Kind);

312

319

321

325

327

329 }

330

332 SourceRange(LAngleBracketLoc, RAngleBracketLoc),

334}

335

342

343

344 bool TypeDependent =

346

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

348 Op.OpRange =

349 CastOperation::OpRangeType(OpLoc, Parens.getBegin(), Parens.getEnd());

350 Op.DestRange = AngleBrackets;

351

352 Op.checkQualifiedDestType();

353

354 switch (Kind) {

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

356

357 case tok::kw_addrspace_cast:

358 if (!TypeDependent) {

359 Op.CheckAddrspaceCast();

362 }

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

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

366

367 case tok::kw_const_cast:

368 if (!TypeDependent) {

369 Op.CheckConstCast();

373 }

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

376 OpLoc, Parens.getEnd(),

377 AngleBrackets));

378

379 case tok::kw_dynamic_cast: {

380

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

383 << "dynamic_cast");

384 }

385

386 if (!TypeDependent) {

387 Op.CheckDynamicCast();

390 }

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

393 &Op.BasePath, DestTInfo,

394 OpLoc, Parens.getEnd(),

395 AngleBrackets));

396 }

397 case tok::kw_reinterpret_cast: {

398 if (!TypeDependent) {

399 Op.CheckReinterpretCast();

403 }

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

406 nullptr, DestTInfo, OpLoc,

408 AngleBrackets));

409 }

410 case tok::kw_static_cast: {

411 if (!TypeDependent) {

412 Op.CheckStaticCast();

416 }

417

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

421 Parens.getEnd(), AngleBrackets));

422 }

423 }

424}

425

437

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

442 Op.OpRange = CastOperation::OpRangeType(KWLoc, KWLoc, RParenLoc);

445

447 Op.CheckBuiltinBitCast();

450 }

451

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

455 return Op.complete(BCE);

456}

457

458

459

461 CastOperation::OpRangeType range,

463 bool listInitialization) {

464 switch (CT) {

465

470 return false;

471

472

476 break;

477 }

478

481 return false;

482

486 range.getBegin(), range, listInitialization)

489 range.getBegin(), range.getParenRange(), listInitialization)

492

493

494

495

496 if (!sequence.Failed())

497 return false;

498

500 default: return false;

501

503

504

505

506

507

508

509

510

511

512

513

514

515

516

517

519 return false;

520 break;

523 break;

524 }

525

527

528 unsigned msg = 0;

530

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

534 if (candidates.empty())

535 msg = diag::err_ovl_no_conversion_in_cast;

536 else

537 msg = diag::err_ovl_no_viable_conversion_in_cast;

539 break;

540

542 msg = diag::err_ovl_ambiguous_conversion_in_cast;

544 break;

545

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

551

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

555 S.PDiag(diag::err_ovl_deleted_conversion_in_cast)

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

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

560 return true;

561 }

562 }

563

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

568 S, howManyCandidates, src);

569

570 return true;

571}

572

573

575 CastOperation::OpRangeType opRange, Expr *src,

576 QualType destType, bool listInitialization) {

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

579 listInitialization))

580 return;

581

582 S.Diag(opRange.getBegin(), msg) << castType

584

585

586 int DifferentPtrness = 0;

590 DifferentPtrness++;

591 }

595 DifferentPtrness--;

596 }

597 if (!DifferentPtrness) {

600 DeclFrom && DeclTo) {

601 if (!DeclFrom->isCompleteDefinition())

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

603 if (!DeclTo->isCompleteDefinition())

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

605 }

606 }

607}

608

609namespace {

610

611

612enum CastAwayConstnessKind {

613

614 CACK_None = 0,

615

616 CACK_Similar = 1,

617

618

619 CACK_SimilarKind = 2,

620

621

622 CACK_Incoherent = 3,

623};

624}

625

626

627

628

629

630

631

632

633

634

635

636

637

638static CastAwayConstnessKind

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

642 if (T->isAnyPointerType()) return Ptr;

643 if (T->isMemberPointerType()) return MemPtr;

644 if (T->isBlockPointerType()) return BlockPtr;

645

646

647 if (T->isConstantArrayType() || T->isIncompleteArrayType()) return Array;

649 };

650

652 if (auto *AT = Context.getAsArrayType(T))

653 return AT->getElementType();

654 return T->getPointeeType();

655 };

656

657 CastAwayConstnessKind Kind;

658

660

661

662

663

665 Kind = CastAwayConstnessKind::CACK_Similar;

666 } else if (Context.UnwrapSimilarTypes(T1, T2)) {

667 Kind = CastAwayConstnessKind::CACK_Similar;

668 } else {

669

670 int T1Class = Classify(T1);

671 if (T1Class == None)

672 return CastAwayConstnessKind::CACK_None;

673

674 int T2Class = Classify(T2);

675 if (T2Class == None)

676 return CastAwayConstnessKind::CACK_None;

677

678 T1 = Unwrap(T1);

679 T2 = Unwrap(T2);

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

681 : CastAwayConstnessKind::CACK_Incoherent;

682 }

683

684

685

686

687

688 while (true) {

689 Context.UnwrapSimilarArrayTypes(T1, T2);

690

691 if (Classify(T1) != Array)

692 break;

693

694 auto T2Class = Classify(T2);

695 if (T2Class == None)

696 break;

697

698 if (T2Class != Array)

699 Kind = CastAwayConstnessKind::CACK_Incoherent;

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

701 Kind = CastAwayConstnessKind::CACK_SimilarKind;

702

703 T1 = Unwrap(T1);

705 }

706

707 return Kind;

708}

709

710

711

712

713

714

715

716static CastAwayConstnessKind

718 bool CheckCVR, bool CheckObjCLifetime,

719 QualType *TheOffendingSrcType = nullptr,

720 QualType *TheOffendingDestType = nullptr,

721 Qualifiers *CastAwayQualifiers = nullptr) {

722

723

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

725 return CastAwayConstnessKind::CACK_None;

726

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

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

734 }

735

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

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

738

739

740

741

742 QualType PrevUnwrappedSrcType = UnwrappedSrcType;

743 QualType PrevUnwrappedDestType = UnwrappedDestType;

744 auto WorstKind = CastAwayConstnessKind::CACK_Similar;

745 bool AllConstSoFar = true;

747 Self.Context, UnwrappedSrcType, UnwrappedDestType)) {

748

749

750 if (Kind > WorstKind)

751 WorstKind = Kind;

752

753

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

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

757

758

759

760

762 UnwrappedDestType->isObjCObjectType())

764

765 if (CheckCVR) {

770

771 if (SrcCvrQuals != DestCvrQuals) {

772 if (CastAwayQualifiers)

773 *CastAwayQualifiers = SrcCvrQuals - DestCvrQuals;

774

775

776 if (!DestCvrQuals.compatiblyIncludes(SrcCvrQuals,

777 Self.getASTContext())) {

778 if (TheOffendingSrcType)

779 *TheOffendingSrcType = PrevUnwrappedSrcType;

780 if (TheOffendingDestType)

781 *TheOffendingDestType = PrevUnwrappedDestType;

782 return WorstKind;

783 }

784

785

786

787 if (!AllConstSoFar)

788 return WorstKind;

789 }

790 }

791

792 if (CheckObjCLifetime &&

794 return WorstKind;

795

796

797

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

799 AllConstSoFar = false;

800 if (TheOffendingSrcType)

801 *TheOffendingSrcType = PrevUnwrappedSrcType;

802 if (TheOffendingDestType)

803 *TheOffendingDestType = PrevUnwrappedDestType;

804 }

805

806 PrevUnwrappedSrcType = UnwrappedSrcType;

807 PrevUnwrappedDestType = UnwrappedDestType;

808 }

809

810 return CastAwayConstnessKind::CACK_None;

811}

812

814 unsigned &DiagID) {

815 switch (CACK) {

816 case CastAwayConstnessKind::CACK_None:

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

818

819 case CastAwayConstnessKind::CACK_Similar:

820

821 case CastAwayConstnessKind::CACK_SimilarKind:

822 DiagID = diag::err_bad_cxx_cast_qualifiers_away;

824

825 case CastAwayConstnessKind::CACK_Incoherent:

826 DiagID = diag::ext_bad_cxx_cast_qualifiers_away_incoherent;

828 }

829

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

831}

832

833

834

835

836void CastOperation::CheckDynamicCast() {

837 CheckNoDerefRAII NoderefCheck(*this);

838

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

841 else if (isPlaceholder())

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

843 if (SrcExpr.isInvalid())

844 return;

845

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

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

848

849

850

851

855 if (DestPointer) {

859 } else {

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

861 << this->DestType << DestRange;

863 return;

864 }

865

866 const auto *DestRecord = DestPointee->getAsCanonical();

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

869 } else if (DestRecord) {

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

871 diag::err_bad_cast_incomplete,

872 DestRange)) {

874 return;

875 }

876 } else {

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

880 return;

881 }

882

883

884

885

886

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

889 if (DestPointer) {

892 } else {

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

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

896 return;

897 }

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

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

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

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

902 }

903 SrcPointee = SrcType;

904 } else {

905

906

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

908 SrcExpr = Self.CreateMaterializeTemporaryExpr(

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

910 SrcPointee = SrcType;

911 }

912

913 const auto *SrcRecord = SrcPointee->getAsCanonical();

914 if (SrcRecord) {

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

916 diag::err_bad_cast_incomplete,

917 SrcExpr.get())) {

919 return;

920 }

921 } else {

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

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

925 return;

926 }

927

928 assert((DestPointer || DestReference) &&

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

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

931 "Bad destination pointee slipped through.");

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

933

934

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

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

939 return;

940 }

941

942

943

944 if (DestRecord == SrcRecord) {

945 Kind = CK_NoOp;

946 return;

947 }

948

949

950

951 if (DestRecord &&

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

953 if (Self.CheckDerivedToBaseConversion(SrcPointee, DestPointee,

954 OpRange.getBegin(), OpRange,

955 &BasePath)) {

957 return;

958 }

959

960 Kind = CK_DerivedToBase;

961 return;

962 }

963

964

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

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

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

971 }

972

973

974

975

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

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

979 return;

980 }

981

982

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

984 bool MicrosoftABI =

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

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

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

989 Self.Diag(OpRange.getBegin(),

990 diag::warn_no_dynamic_cast_with_rtti_disabled)

991 << isClangCL;

992 }

993

994

995

996 if (DestRecord) {

997 auto *DestDecl = DestRecord->getAsCXXRecordDecl();

998 if (DestDecl->isEffectivelyFinal())

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

1000 }

1001

1002

1003 Kind = CK_Dynamic;

1004}

1005

1006

1007

1008

1009

1010

1011void CastOperation::CheckConstCast() {

1012 CheckNoDerefRAII NoderefCheck(*this);

1013

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

1016 else if (isPlaceholder())

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

1018 if (SrcExpr.isInvalid())

1019 return;

1020

1021 unsigned msg = diag::err_bad_cxx_cast_generic;

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

1023 if (TCR != TC_Success && msg != 0) {

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

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

1026 }

1029}

1030

1031void CastOperation::CheckAddrspaceCast() {

1032 unsigned msg = diag::err_bad_cxx_cast_generic;

1033 auto TCR =

1035 if (TCR != TC_Success && msg != 0) {

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

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

1038 }

1041}

1042

1043

1044

1047 CastOperation::OpRangeType OpRange) {

1049

1050

1054

1055

1056

1057

1059 return;

1060

1062

1064 return;

1065

1066 enum {

1067 ReinterpretUpcast,

1068 ReinterpretDowncast

1069 } ReinterpretKind;

1070

1072

1074 ReinterpretKind = ReinterpretUpcast;

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

1076 ReinterpretKind = ReinterpretDowncast;

1077 else

1078 return;

1079

1081 bool NonZeroOffset = false;

1083 E = BasePaths.end();

1084 I != E; ++I) {

1087 bool IsVirtual = false;

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

1089 IElem != EElem; ++IElem) {

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

1091 if (IsVirtual)

1092 break;

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

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

1095

1096

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

1100 !ClassDefinition->isCompleteDefinition())

1101 return;

1102

1104 Self.Context.getASTRecordLayout(Class);

1106 }

1107 if (!IsVirtual) {

1108

1109 if (Offset.isZero())

1110 return;

1111

1112 else

1113 NonZeroOffset = true;

1114 }

1116 }

1117

1118 (void) NonZeroOffset;

1119 assert((VirtualBase || NonZeroOffset) &&

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

1121

1123 ReinterpretKind == ReinterpretUpcast? DestType : SrcType;

1125 ReinterpretKind == ReinterpretUpcast? SrcType : DestType;

1126

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

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

1130 << OpRange;

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

1132 << int(ReinterpretKind)

1134}

1135

1139 return true;

1140

1141

1144 if (Context.getTypeSizeInChars(SrcType) ==

1145 Context.getTypeSizeInChars(DestType))

1146 return true;

1147

1148 return Context.hasSameUnqualifiedType(SrcType, DestType);

1149}

1150

1153 unsigned int DiagID = 0;

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

1155 diag::warn_cast_function_type};

1158 DiagID = ID;

1159 break;

1160 }

1161 }

1162 if (!DiagID)

1163 return 0;

1164

1177 } else {

1178 return 0;

1179 }

1180 assert(SrcFTy && DstFTy);

1181

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

1183 return 0;

1184

1185

1186 if (DiagID == diag::warn_cast_function_type_strict)

1187 return DiagID;

1188

1190 if (T->getReturnType()->isVoidType())

1191 return false;

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

1194 return false;

1195 };

1196

1198

1199

1200

1201

1202

1203

1204

1205

1206 if (T->getReturnType()->isIntegerType())

1207 return false;

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

1210 return true;

1211 };

1212

1213

1214 if (IsVoidVoid(SrcFTy) || IsVoidVoid(DstFTy))

1215 return 0;

1216

1217

1218

1219

1220 if (Self.getASTContext().getTargetInfo().getTriple().isOSWindows() &&

1221 IsFarProc(SrcFTy))

1222 return 0;

1223

1224

1226 Self.Context))

1227 return DiagID;

1228

1229

1231 return 0;

1232

1233

1234

1237

1238

1239

1240 unsigned NumParams = SrcFPTy->getNumParams();

1241 unsigned DstNumParams = DstFPTy->getNumParams();

1242 if (NumParams > DstNumParams) {

1243 if (!DstFPTy->isVariadic())

1244 return DiagID;

1245 NumParams = DstNumParams;

1246 } else if (NumParams < DstNumParams) {

1247 if (!SrcFPTy->isVariadic())

1248 return DiagID;

1249 }

1250

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

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

1254 return DiagID;

1255

1256 return 0;

1257}

1258

1259

1260

1261

1262

1263

1264void CastOperation::CheckReinterpretCast() {

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

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

1267 else

1268 checkNonOverloadPlaceholders();

1269 if (SrcExpr.isInvalid())

1270 return;

1271

1272 unsigned msg = diag::err_bad_cxx_cast_generic;

1275 false, OpRange, msg, Kind);

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

1277 if (SrcExpr.isInvalid())

1278 return;

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

1280

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

1283 << DestType << OpRange;

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

1285

1286 } else {

1288 DestType, false);

1289 }

1290 }

1291

1293 if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())

1295 true);

1297

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

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

1301 } else {

1303 }

1304}

1305

1306

1307

1308

1309

1310void CastOperation::CheckStaticCast() {

1311 CheckNoDerefRAII NoderefCheck(*this);

1312

1313 if (isPlaceholder()) {

1314 checkNonOverloadPlaceholders();

1315 if (SrcExpr.isInvalid())

1316 return;

1317 }

1318

1319

1320

1321

1323 Kind = CK_ToVoid;

1324

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

1326 Self.ResolveAndFixSingleFunctionTemplateSpecialization(SrcExpr,

1327 false,

1328 true,

1329 OpRange, DestType, diag::err_bad_static_cast_overload);

1330 if (SrcExpr.isInvalid())

1331 return;

1332 }

1333

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

1335 return;

1336 }

1337

1339 !isPlaceholder(BuiltinType::Overload)) {

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

1341 if (SrcExpr.isInvalid())

1342 return;

1343 }

1344

1345 unsigned msg = diag::err_bad_cxx_cast_generic;

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

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

1350 if (SrcExpr.isInvalid())

1351 return;

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

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

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

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

1358 } else {

1360 false);

1361 }

1362 }

1363

1365 if (Kind == CK_BitCast)

1366 checkCastAlign();

1367 if (Self.getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())

1369 } else {

1371 }

1372}

1373

1376 if (!SrcPtrType)

1377 return false;

1379 if (!DestPtrType)

1380 return false;

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

1383}

1384

1385

1386

1387

1390 CastOperation::OpRangeType OpRange,

1391 unsigned &msg, CastKind &Kind,

1393 bool ListInitialization) {

1394

1397

1398

1399

1400

1401

1402

1403

1404

1405

1406

1407

1408

1409

1410

1411

1412

1414

1415

1416

1417

1419 OpRange, msg, Kind, BasePath);

1421 return tcr;

1422

1423

1424

1425

1427 Kind, BasePath, msg);

1429 return tcr;

1430

1431

1432

1434 Kind, ListInitialization);

1438 return tcr;

1439

1440

1441

1442

1443

1444

1445

1446

1447

1448

1449

1451

1452

1453

1454

1455 if (const EnumType *Enum = dyn_cast(SrcType)) {

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

1458 Kind = CK_IntegralToBoolean;

1461 Kind = CK_IntegralCast;

1464 Kind = CK_IntegralToFloating;

1466 }

1467 }

1468 }

1469

1470

1471

1472

1473

1474

1475

1476

1477

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

1480 diag::err_bad_cast_incomplete)) {

1483 }

1485

1486

1488 Kind = ED->isFixed() && ED->getIntegerType()->isBooleanType()

1489 ? CK_IntegralToBoolean

1490 : CK_IntegralCast;

1493 Kind = CK_FloatingToIntegral;

1495 }

1496 }

1497

1498

1499

1501 Kind, BasePath);

1503 return tcr;

1504

1505

1506

1507

1509 OpRange, msg, Kind, BasePath);

1511 return tcr;

1512

1513

1514

1515

1522

1523

1524

1525 if (!CStyle) {

1532 if (DestPointeeQuals != SrcPointeeQuals &&

1534 Self.getASTContext())) {

1535 msg = diag::err_bad_cxx_cast_qualifiers_away;

1537 }

1538 }

1540 ? CK_AddressSpaceConversion

1541 : CK_BitCast;

1543 }

1544

1545

1546

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

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

1550 Kind = CK_BitCast;

1552 }

1553 }

1555

1556

1557 Kind = CK_CPointerToObjCPointerCast;

1559 }

1561

1562 Kind = CK_AnyPointerToBlockPointerCast;

1564 }

1565 }

1566 }

1567

1570 Kind = CK_BitCast;

1572 }

1573

1574

1575 if (!CStyle &&

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

1578

1579

1580

1582 if (const auto *DestPointer = DestType->getAs<PointerType>())

1583 if (SrcPointer->getPointeeType()->isRecordType() &&

1585 msg = diag::err_bad_cxx_cast_unrelated_class;

1586

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

1591 }

1593 }

1594

1595

1597}

1598

1599

1601 QualType DestType, bool CStyle,

1604

1605

1606

1608 if (!R)

1610

1613

1614

1615

1618 if (CStyle) {

1621 }

1622

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

1629

1630

1631

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

1633 : diag::err_bad_rvalue_to_rvalue_cast;

1635 }

1636

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

1638 Kind = CK_DerivedToBase;

1639 if (Self.CheckDerivedToBaseConversion(FromType, ToType,

1641 &BasePath, CStyle)) {

1642 msg = 0;

1644 }

1645 } else

1646 Kind = CK_NoOp;

1647

1649}

1650

1651

1653 QualType DestType, bool CStyle,

1654 CastOperation::OpRangeType OpRange,

1655 unsigned &msg, CastKind &Kind,

1657

1658

1659

1660

1661

1662

1663

1664

1665

1667 if (!DestReference) {

1669 }

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

1672

1673 msg = diag::err_bad_cxx_cast_rvalue;

1675 }

1676

1678

1679

1680

1681

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

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

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

1686 BasePath);

1687}

1688

1689

1691 QualType DestType, bool CStyle,

1692 CastOperation::OpRangeType OpRange,

1693 unsigned &msg, CastKind &Kind,

1695

1696

1697

1698

1699

1700

1701

1702

1704 if (!DestPointer) {

1706 }

1707

1709 if (!SrcPointer) {

1710 msg = diag::err_bad_static_cast_pointer_nonpointer;

1712 }

1713

1717 CStyle, OpRange, SrcType, DestType, msg, Kind,

1718 BasePath);

1719}

1720

1721

1722

1723

1726 CastOperation::OpRangeType OpRange,

1728 unsigned &msg, CastKind &Kind,

1730

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

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

1734

1735

1736 if (!DestType->getAs() || !SrcType->getAs()) {

1738 }

1739

1740 CXXBasePaths Paths(true, true,

1741 true);

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

1744 }

1745

1746

1747

1748

1749

1750

1751

1752

1753

1754

1755

1756

1757

1758

1759

1760

1761

1762

1763

1764

1765 if (!CStyle &&

1767 msg = diag::err_bad_cxx_cast_qualifiers_away;

1769 }

1770

1772

1773

1774

1775

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

1780 }

1781 std::string PathDisplayStr;

1782 std::set DisplayedPaths;

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

1785

1786

1787 PathDisplayStr += "\n ";

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

1791 }

1792 }

1793

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

1797 << PathDisplayStr << OpRange;

1798 msg = 0;

1800 }

1801

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

1805 << OrigSrcType << OrigDestType << VirtualBase << OpRange;

1806 msg = 0;

1808 }

1809

1810 if (!CStyle) {

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

1812 SrcType, DestType,

1814 diag::err_downcast_from_inaccessible_base)) {

1818 break;

1819

1821 msg = 0;

1823 }

1824 }

1825

1826 Self.BuildBasePathArray(Paths, BasePath);

1827 Kind = CK_BaseToDerived;

1829}

1830

1831

1832

1833

1834

1835

1836

1837

1840 bool CStyle,

1841 CastOperation::OpRangeType OpRange,

1842 unsigned &msg, CastKind &Kind,

1845 if (!DestMemPtr)

1847

1848 bool WasOverloadedFunction = false;

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

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

1853 FoundOverload)) {

1855 SrcType = Self.Context.getMemberPointerType(

1856 Fn->getType(), std::nullopt, M->getParent());

1857 WasOverloadedFunction = true;

1858 }

1859 }

1860

1861 switch (Self.CheckMemberPointerConversion(

1862 SrcType, DestMemPtr, Kind, BasePath, OpRange.getBegin(), OpRange, CStyle,

1865 if (Kind == CK_NullToMemberPointer) {

1866 msg = diag::err_bad_static_cast_member_pointer_nonmp;

1868 }

1869 break;

1876 msg = 0;

1878 }

1879

1880 if (WasOverloadedFunction) {

1881

1882

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

1884 DestType,

1885 true,

1886 FoundOverload);

1887 if (!Fn) {

1888 msg = 0;

1890 }

1891

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

1894 msg = 0;

1896 }

1897 }

1899}

1900

1901

1902

1903

1904

1905

1909 CastOperation::OpRangeType OpRange,

1910 unsigned &msg, CastKind &Kind,

1911 bool ListInitialization) {

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

1914 diag::err_bad_cast_incomplete) ||

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

1916 diag::err_allocation_of_abstract_type)) {

1917 msg = 0;

1919 }

1920 }

1921

1926 ListInitialization)

1929 OpRange.getBegin(), OpRange.getParenRange(), ListInitialization)

1931 Expr *SrcExprRaw = SrcExpr.get();

1932

1933

1934

1936

1937

1938

1939

1940

1941

1946

1948 if (Result.isInvalid()) {

1949 msg = 0;

1951 }

1952

1954 Kind = CK_ConstructorConversion;

1955 else

1956 Kind = CK_NoOp;

1957

1958 SrcExpr = Result;

1960}

1961

1962

1963

1965 QualType DestType, bool CStyle,

1966 unsigned &msg) {

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

1969 bool NeedToMaterializeTemporary = false;

1970

1972

1973

1974

1975

1976

1977

1978

1979

1980

1981

1982

1984

1985

1986

1987 msg = diag::err_bad_cxx_cast_rvalue;

1989 }

1990

1993

1994

1995 msg = diag::err_bad_cxx_cast_rvalue;

1997 }

1998

1999

2000

2001 NeedToMaterializeTemporary = true;

2002 }

2003

2004

2005

2006

2007

2008

2010 msg = diag::err_bad_cxx_cast_bitfield;

2012 }

2013

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

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

2016 }

2017

2018

2019

2020

2024

2025

2026

2027

2028

2029 if (!CStyle)

2030 msg = diag::err_bad_const_cast_dest;

2032 }

2035

2036

2037

2038 if (!CStyle)

2039 msg = diag::err_bad_const_cast_dest;

2041 }

2042

2043

2044

2045

2046

2047

2048

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

2051

2052 if (NeedToMaterializeTemporary)

2053

2054

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

2056 SrcExpr.get(),

2057 false);

2058

2060}

2061

2062

2063

2064

2065

2066

2068 bool IsDereference,

2070 unsigned DiagID = IsDereference ?

2071 diag::warn_pointer_indirection_from_incompatible_type :

2072 diag::warn_undefined_reinterpret_cast;

2073

2074 if (Diags.isIgnored(DiagID, Range.getBegin()))

2075 return;

2076

2078 if (IsDereference) {

2080 return;

2081 }

2084 } else {

2086 return;

2087 }

2088 SrcTy = SrcType;

2090 }

2091

2092

2093 if (Context.hasSameUnqualifiedType(DestTy, SrcTy)) {

2094 return;

2095 }

2096

2099 return;

2100 }

2101

2104 return;

2105

2106

2109 if (Context.getTypeSize(DestTy) == Context.getTypeSize(SrcTy)) {

2110 return;

2111 }

2112 }

2113

2115 return;

2116 }

2117

2118 Diag(Range.getBegin(), DiagID) << SrcType << DestType << Range;

2119}

2120

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

2125 return;

2127 if (SrcPtrTy->isObjCSelType()) {

2133 diag::warn_cast_pointer_from_sel)

2135 }

2136}

2137

2138

2139

2142 CastOperation::OpRangeType OpRange) {

2143

2144

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

2148 return;

2149 const auto *SrcFTy =

2151 const auto *DstFTy =

2153 CallingConv SrcCC = SrcFTy->getCallConv();

2155 if (SrcCC == DstCC)

2156 return;

2157

2158

2159

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

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

2164 auto *DRE = dyn_cast(Src);

2165 if (!DRE)

2166 return;

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

2168 if (!FD)

2169 return;

2170

2171

2172

2173

2174

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

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

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

2178 return;

2179

2180

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

2184 << SrcCCName << DstCCName << OpRange;

2185

2186

2187

2188

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

2190 return;

2191

2192

2193

2194

2195

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

2200 llvm::raw_svector_ostream OS(CCAttrText);

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

2202

2203 OS << "__" << DstCCName;

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

2208 } else {

2209

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

2211 AttrTokens.push_back(tok::kw___attribute);

2212 AttrTokens.push_back(tok::l_paren);

2213 AttrTokens.push_back(tok::l_paren);

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

2218 AttrTokens.push_back(tok::r_paren);

2219 AttrTokens.push_back(tok::r_paren);

2220 }

2222 if (!AttrSpelling.empty())

2223 CCAttrText = AttrSpelling;

2224 OS << ' ';

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

2227}

2228

2233

2234

2235

2236

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

2242 Self.Context.getTypeSize(SrcType)) {

2243

2244

2245

2246

2247

2249 diag::warn_int_to_void_pointer_cast

2250 : diag::warn_int_to_pointer_cast;

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

2252 }

2253}

2254

2257

2258

2259

2260

2261

2262

2263 Expr *E = Result.get();

2264

2265

2266 if (Self.ResolveAndFixSingleFunctionTemplateSpecialization(

2267 Result,

2270 ) &&

2271 Result.isUsable())

2272 return true;

2273

2274

2275

2276 Result = E;

2277 if (Self.resolveAndFixAddressOfSingleOverloadCandidate(

2278 Result, true))

2279 return false;

2280 return Result.isUsable();

2281}

2282

2284 QualType DestType, bool CStyle,

2285 CastOperation::OpRangeType OpRange,

2286 unsigned &msg, CastKind &Kind) {

2287 bool IsLValueCast = false;

2288

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

2291

2292

2293

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

2298

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

2300 SrcExpr = FixedExpr;

2302 }

2303

2306

2307

2308 msg = diag::err_bad_cxx_cast_rvalue;

2310 }

2311

2312 if (!CStyle) {

2313 Self.CheckCompatibleReinterpretCast(SrcType, DestType,

2314 false, OpRange);

2315 }

2316

2317

2318

2319

2320

2321 const char *inappropriate = nullptr;

2324 break;

2326 msg = diag::err_bad_cxx_cast_bitfield;

2328

2331 inappropriate = "matrix element";

2332 break;

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

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

2335 break;

2336 }

2337 if (inappropriate) {

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

2339 << inappropriate << DestType

2343 }

2344

2345

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

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

2348

2349 IsLValueCast = true;

2350 }

2351

2352

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

2354

2357 if (DestMemPtr && SrcMemPtr) {

2358

2359

2360

2361

2363 SrcMemPtr->isMemberFunctionPointer())

2365

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

2367

2368

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

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

2371 }

2372

2373

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

2375 Self.Context.getTypeSize(SrcMemPtr)) {

2376 msg = diag::err_bad_cxx_cast_member_pointer_size;

2378 }

2379

2380

2381

2382

2383

2384 if (auto CACK =

2386 CStyle))

2388

2389

2390 assert(!IsLValueCast);

2391 Kind = CK_ReinterpretMemberPointer;

2393 }

2394

2395

2397

2398

2399

2400

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

2402 Self.Context.getTypeSize(DestType)) {

2403 msg = diag::err_bad_reinterpret_cast_small_int;

2405 }

2406 Kind = CK_PointerToIntegral;

2408 }

2409

2410

2411

2412 bool destIsVector = DestType->isVectorType();

2414 if (srcIsVector || destIsVector) {

2415

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

2417 Kind = CK_BitCast;

2419 }

2420

2421

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

2423 Kind = CK_BitCast;

2425 }

2426

2427

2428

2429

2433

2434

2435

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

2437 Kind = CK_BitCast;

2439 }

2440

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

2443

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

2445 Kind = CK_BitCast;

2447 }

2448 }

2449 }

2450

2451

2452 if (!destIsVector)

2453 msg = diag::err_bad_cxx_cast_vector_to_scalar_different_size;

2454 else if (!srcIsVector)

2455 msg = diag::err_bad_cxx_cast_scalar_to_vector_different_size;

2456 else

2457 msg = diag::err_bad_cxx_cast_vector_to_vector_different_size;

2458

2460 }

2461

2462 if (SrcType == DestType) {

2463

2464

2465

2466

2467

2468

2469

2470

2471 Kind = CK_NoOp;

2478 }

2479 return Result;

2480 }

2481

2486 if (!destIsPtr && !srcIsPtr) {

2487

2488

2490 }

2491

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

2494

2495

2496

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

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

2499 bool MicrosoftException =

2501 if (MicrosoftException) {

2503 ? diag::warn_void_pointer_to_int_cast

2504 : diag::warn_pointer_to_int_cast;

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

2506 } else {

2507 msg = diag::err_bad_reinterpret_cast_small_int;

2509 }

2510 }

2511 Kind = CK_PointerToIntegral;

2513 }

2514

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

2518

2519

2520

2521

2522 Kind = CK_IntegralToPointer;

2524 }

2525

2526 if (!destIsPtr || !srcIsPtr) {

2527

2528

2530 }

2531

2532

2536

2537

2538

2540 if (auto CACK =

2542 CStyle))

2544

2546 Kind = CK_AddressSpaceConversion;

2548 if (!CStyle &&

2552 }

2553 } else if (IsLValueCast) {

2554 Kind = CK_LValueBitCast;

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

2559 Kind = CK_AnyPointerToBlockPointerCast;

2560 } else {

2561 Kind = CK_BitCast;

2562 }

2563 } else {

2564 Kind = CK_BitCast;

2565 }

2566

2567

2568

2570 return SuccessResult;

2571 }

2572 if (CStyle)

2574

2576

2577

2578

2579

2582

2583

2584 return SuccessResult;

2585 }

2586

2587

2588

2589

2590

2591

2592

2593 Self.Diag(OpRange.getBegin(),

2594 Self.getLangOpts().CPlusPlus11 ?

2595 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)

2596 << OpRange;

2597 return SuccessResult;

2598 }

2599

2601

2602 Self.Diag(OpRange.getBegin(),

2603 Self.getLangOpts().CPlusPlus11 ?

2604 diag::warn_cxx98_compat_cast_fn_obj : diag::ext_cast_fn_obj)

2605 << OpRange;

2606 return SuccessResult;

2607 }

2608

2609

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

2618 Self.Diag(OpRange.getBegin(),

2619 diag::warn_bad_cxx_cast_nested_pointer_addr_space)

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

2621 break;

2622 }

2625 }

2626

2627

2628

2629

2630

2631

2632 return SuccessResult;

2633}

2634

2636 QualType DestType, bool CStyle,

2637 unsigned &msg, CastKind &Kind) {

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

2639

2640

2642

2643

2644

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

2646

2647

2648

2650 if (!SrcPtrType)

2653 if (!DestPtrType)

2655 auto SrcPointeeType = SrcPtrType->getPointeeType();

2656 auto DestPointeeType = DestPtrType->getPointeeType();

2657 if (!DestPointeeType.isAddressSpaceOverlapping(SrcPointeeType,

2658 Self.getASTContext())) {

2659 msg = diag::err_bad_cxx_cast_addr_space_mismatch;

2661 }

2662 auto SrcPointeeTypeWithoutAS =

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

2664 auto DestPointeeTypeWithoutAS =

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

2666 if (Self.Context.hasSameType(SrcPointeeTypeWithoutAS,

2667 DestPointeeTypeWithoutAS)) {

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

2669 ? CK_NoOp

2670 : CK_AddressSpaceConversion;

2672 } else {

2674 }

2675}

2676

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

2678

2679

2680

2681

2682

2683

2684

2685

2686

2687

2688

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

2690 const Type *DestPtr, *SrcPtr;

2691 bool Nested = false;

2692 unsigned DiagID = diag::err_typecheck_incompatible_address_space;

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

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

2695

2701 if (Nested

2704 Self.getASTContext())) {

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

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

2708 if (!Nested)

2710 return;

2711 }

2712

2715 Nested = true;

2716 DiagID = diag::ext_nested_pointer_qualifier_mismatch;

2717 }

2718 }

2719}

2720

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

2725

2729 return true;

2730 }

2731 return false;

2732}

2733

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

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

2740 diag::err_invalid_conversion_between_vector_and_integer)

2741 << VecTy << SrcTy << R;

2742 return true;

2743 }

2744 return false;

2745}

2746

2747void CastOperation::CheckCXXCStyleCast(bool FunctionalStyle,

2748 bool ListInitialization) {

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

2750

2751

2752 if (isPlaceholder()) {

2753

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

2755 SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType,

2756 SrcExpr.get(), Kind,

2757 ValueKind, BasePath);

2758 return;

2759 }

2760

2761 checkNonOverloadPlaceholders();

2762 if (SrcExpr.isInvalid())

2763 return;

2764 }

2765

2766

2767

2768

2770 Kind = CK_ToVoid;

2771

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

2773 Self.ResolveAndFixSingleFunctionTemplateSpecialization(

2774 SrcExpr, false,

2775 true, DestRange, DestType,

2776 diag::err_bad_cstyle_cast_overload);

2777 if (SrcExpr.isInvalid())

2778 return;

2779 }

2780

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

2782 return;

2783 }

2784

2785

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

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

2788 assert(Kind == CK_Dependent);

2789 return;

2790 }

2791

2795 if (Self.getLangOpts().HLSL) {

2796 if (CheckHLSLCStyleCast(CCK))

2797 return;

2798 }

2799

2801 !isPlaceholder(BuiltinType::Overload)) {

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

2803 if (SrcExpr.isInvalid())

2804 return;

2805 }

2806

2807

2809 if (Self.CheckAltivecInitFromScalar(OpRange, DestType,

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

2812 return;

2813 }

2814 if (Self.ShouldSplatAltivecScalarInCast(vecTy) &&

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

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

2817 Kind = CK_VectorSplat;

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

2819 return;

2820 }

2821 }

2822

2823

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

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

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

2829 return;

2830 }

2831

2832

2833

2834

2835

2836

2837

2838

2839

2840

2841

2842

2843

2844 unsigned msg = diag::err_bad_cxx_cast_generic;

2846 true, msg);

2847 if (SrcExpr.isInvalid())

2848 return;

2850 Kind = CK_NoOp;

2851

2854 Kind);

2855 if (SrcExpr.isInvalid())

2856 return;

2857

2859

2860

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

2862 BasePath, ListInitialization);

2863 if (SrcExpr.isInvalid())

2864 return;

2865

2867

2869 OpRange, msg, Kind);

2870 if (SrcExpr.isInvalid())

2871 return;

2872 }

2873 }

2874 }

2875

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

2878 checkObjCConversion(CCK);

2879

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

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

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

2884 DestType,

2885 true,

2887 if (Fn) {

2888

2889

2890

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

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

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

2896 }

2897 } else {

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

2900 }

2901 }

2902

2904 if (Kind == CK_BitCast)

2905 checkCastAlign();

2906

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

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

2910

2911 } else {

2913 }

2914}

2915

2916

2917

2918

2920 assert(Self.getLangOpts().HLSL && "Must be HLSL!");

2921 QualType SrcTy = SrcExpr.get()->getType();

2922

2923

2924

2925 if (Self.HLSL().CanPerformElementwiseCast(SrcExpr.get(), DestType)) {

2927 SrcExpr = Self.ImpCastExprToType(

2928 SrcExpr.get(), Self.Context.getArrayParameterType(SrcTy),

2929 CK_HLSLArrayRValue, VK_PRValue, nullptr, CCK);

2930 else

2931 SrcExpr = Self.DefaultLvalueConversion(SrcExpr.get());

2932 Kind = CK_HLSLElementwiseCast;

2933 return true;

2934 }

2935

2936

2937

2938

2939 if (Self.HLSL().CanPerformAggregateSplatCast(SrcExpr.get(), DestType)) {

2940 SrcExpr = Self.DefaultLvalueConversion(SrcExpr.get());

2942

2944 SrcExpr = Self.ImpCastExprToType(

2945 SrcExpr.get(), VT->getElementType(), CK_HLSLVectorTruncation,

2946 SrcExpr.get()->getValueKind(), nullptr, CCK);

2947

2948

2950 SrcExpr = Self.ImpCastExprToType(

2951 SrcExpr.get(), DVT->getElementType(),

2952 Self.PrepareScalarCast(SrcExpr, DVT->getElementType()),

2953 SrcExpr.get()->getValueKind(), nullptr, CCK);

2954 Kind = CK_HLSLAggregateSplatCast;

2955 return true;

2956 }

2957

2958

2959

2961 Self.Diag(OpRange.getBegin(), diag::err_bad_cxx_cast_generic)

2962 << 4 << SrcTy << DestType;

2964 return true;

2965 }

2966 return false;

2967}

2968

2969

2970

2971

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

2976 return;

2977

2979 return;

2980

2983 return;

2986 return;

2990 return;

2992 return;

2994 return;

2996 return;

2998 return;

3000 return;

3001

3003 diag::warn_bad_function_cast)

3005}

3006

3007

3008void CastOperation::CheckCStyleCast() {

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

3010

3011

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

3013 SrcExpr = Self.checkUnknownAnyCast(DestRange, DestType,

3014 SrcExpr.get(), Kind,

3015 ValueKind, BasePath);

3016 return;

3017 }

3018

3019

3020

3022

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

3024 if (SrcExpr.isInvalid())

3025 return;

3026

3027

3028 Kind = CK_ToVoid;

3029 return;

3030 }

3031

3032

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

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

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

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

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

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

3039 assert(Kind == CK_Dependent);

3040 return;

3041 }

3042

3043

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

3046 if (FunctionDecl *FD = Self.ResolveAddressOfOverloadedFunction(

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

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

3049 else

3050 return;

3051 assert(SrcExpr.isUsable());

3052 }

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

3054 if (SrcExpr.isInvalid())

3055 return;

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

3057

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

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

3062 return;

3063 }

3064

3066

3067 checkAddressSpaceCast(SrcType, DestType);

3068 if (SrcExpr.isInvalid())

3069 return;

3070

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

3072 diag::err_typecheck_cast_to_incomplete)) {

3074 return;

3075 }

3076

3077

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

3080 Kind = CK_NoOp;

3081 return;

3082 }

3083

3084

3086 Self.isValidSveBitcast(SrcType, DestType)) {

3087 Kind = CK_BitCast;

3088 return;

3089 }

3090

3091

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

3094 Kind = CK_BitCast;

3095 return;

3096 }

3097

3100 if (const RecordType *DestRecordTy =

3102 if (Self.Context.hasSameUnqualifiedType(DestType, SrcType)) {

3103

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

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

3106 Kind = CK_NoOp;

3107 return;

3108 }

3109

3110

3113 SrcType)) {

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

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

3116 Kind = CK_ToUnion;

3117 return;

3118 }

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

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

3122 return;

3123 }

3124 }

3125

3126

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

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

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

3131 if (0 == CastInt) {

3132 Kind = CK_ZeroToOCLOpaqueType;

3133 return;

3134 }

3135 Self.Diag(OpRange.getBegin(),

3136 diag::err_opencl_cast_non_zero_to_event_t)

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

3139 return;

3140 }

3141 }

3142

3143

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

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

3147 return;

3148 }

3149

3150

3151

3152

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

3156 diag::err_typecheck_expect_scalar_operand)

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

3159 return;

3160 }

3161

3162

3163

3164

3165

3167

3168

3169

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

3173 << 0 << DestType;

3175 return;

3176 }

3179 Self.Context, DestType, CK_PointerToBoolean, SrcExpr.get(), nullptr,

3181

3183

3184

3188 Self.CurFPFeatureOverrides());

3189 }

3190 }

3191

3193 if (!SrcExpr.get()->isNullPointerConstant(Self.Context,

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

3196 << 1 << SrcType;

3198 return;

3199 }

3200

3201

3204 Self.CurFPFeatureOverrides());

3205 }

3206

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

3209 return;

3210 }

3211

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

3215 return;

3216 }

3217

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

3221 return;

3222 }

3223 if (Self.ShouldSplatAltivecScalarInCast(DestVecTy) &&

3225 Kind = CK_VectorSplat;

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

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

3229 }

3230 return;

3231 }

3232

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

3236 return;

3237 }

3238

3239

3240

3241

3242

3243

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

3247 return;

3248 }

3249

3250

3251

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

3255 diag::err_cast_pointer_from_non_pointer_int)

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

3258 return;

3259 }

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

3266 diag::err_cast_pointer_to_non_pointer_int)

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

3269 return;

3270 }

3271

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

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

3275

3276

3277

3278

3279

3280 unsigned Diag;

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

3283 : diag::warn_void_pointer_to_int_cast;

3285 Diag = diag::warn_pointer_to_enum_cast;

3286 else

3287 Diag = diag::warn_pointer_to_int_cast;

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

3289 }

3290 }

3291

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

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

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

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

3298 return;

3299 }

3300 }

3301

3302

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

3305 if (SrcExpr.isInvalid())

3306 return;

3307

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

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

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

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

3317 diag::err_typecheck_incompatible_ownership)

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

3320 return;

3321 }

3322 }

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

3324 SrcType)) {

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

3326 diag::err_arc_convesion_of_weak_unavailable)

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

3329 return;

3330 }

3331 }

3332

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

3335

3339

3342

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

3344 SrcRD != DestRD) {

3345

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

3347 << SrcType << DestType;

3349 return;

3350 }

3351 }

3352

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

3357 if (SrcExpr.isInvalid())

3358 return;

3359

3360 if (Kind == CK_BitCast)

3361 checkCastAlign();

3362}

3363

3364void CastOperation::CheckBuiltinBitCast() {

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

3366

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

3368 diag::err_typecheck_cast_to_incomplete) ||

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

3370 diag::err_incomplete_type)) {

3372 return;

3373 }

3374

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

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

3377 false);

3378

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

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

3381 if (DestSize != SourceSize) {

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

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

3386 return;

3387 }

3388

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

3391 << 1;

3393 return;

3394 }

3395

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

3398 << 0;

3400 return;

3401 }

3402

3403 Kind = CK_LValueToRValueBitCast;

3404}

3405

3406

3407

3411 return;

3412

3416 return;

3417

3418 QualType TheOffendingSrcType, TheOffendingDestType;

3421 &TheOffendingSrcType, &TheOffendingDestType,

3422 &CastAwayQualifiers) !=

3423 CastAwayConstnessKind::CACK_Similar)

3424 return;

3425

3426

3427 int qualifiers = -1;

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

3429 qualifiers = 0;

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

3431 qualifiers = 1;

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

3433 qualifiers = 2;

3434 }

3435

3436 if (qualifiers == -1)

3438 << SrcType << DestType;

3439 else

3441 << TheOffendingSrcType << TheOffendingDestType << qualifiers;

3442}

3443

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

3450 Op.OpRange = CastOperation::OpRangeType(LPLoc, LPLoc, CastExpr->getEndLoc());

3451

3453 Op.CheckCXXCStyleCast( false,

3455 } else {

3456 Op.CheckCStyleCast();

3457 }

3458

3461

3462

3464

3465 Op.checkQualifiedDestType();

3466

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

3470}

3471

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

3480 Op.OpRange =

3481 CastOperation::OpRangeType(Op.DestRange.getBegin(), LPLoc, RPLoc);

3482

3483 Op.CheckCXXCStyleCast(true, false);

3486

3487 Op.checkQualifiedDestType();

3488

3489

3491

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

3495}

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 TryCastResult TryStaticDowncast(Sema &Self, CanQualType SrcType, CanQualType DestType, bool CStyle, CastOperation::OpRangeType OpRange, QualType OrigSrcType, QualType OrigDestType, unsigned &msg, CastKind &Kind, CXXCastPath &BasePath)

TryStaticDowncast - Common functionality of TryStaticReferenceDowncast and TryStaticPointerDowncast.

Definition SemaCast.cpp:1724

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

Definition SemaCast.cpp:717

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

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

Definition SemaCast.cpp:1690

static TryCastResult getCastAwayConstnessCastKind(CastAwayConstnessKind CACK, unsigned &DiagID)

Definition SemaCast.cpp:813

static bool IsAddressSpaceConversion(QualType SrcType, QualType DestType)

Definition SemaCast.cpp:1374

CastType

Definition SemaCast.cpp:49

@ CT_Reinterpret

reinterpret_cast

Definition SemaCast.cpp:52

@ CT_Functional

Type(expr)

Definition SemaCast.cpp:55

@ CT_Dynamic

dynamic_cast

Definition SemaCast.cpp:53

@ CT_Const

const_cast

Definition SemaCast.cpp:50

@ CT_CStyle

(Type)expr

Definition SemaCast.cpp:54

@ CT_Addrspace

addrspace_cast

Definition SemaCast.cpp:56

@ CT_Static

static_cast

Definition SemaCast.cpp:51

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.

Definition SemaCast.cpp:1964

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

Definition SemaCast.cpp:2283

static bool isValidCast(TryCastResult TCR)

Definition SemaCast.cpp:45

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

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

Definition SemaCast.cpp:1652

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

Definition SemaCast.cpp:1136

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

Definition SemaCast.cpp:1151

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

Tests whether a conversion according to N2844 is valid.

Definition SemaCast.cpp:1600

TryCastResult

Definition SemaCast.cpp:36

@ TC_Success

The cast method is appropriate and successful.

Definition SemaCast.cpp:38

@ TC_Extension

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

Definition SemaCast.cpp:39

@ TC_Failed

The cast method is appropriate, but failed.

Definition SemaCast.cpp:41

@ TC_NotApplicable

The cast method is not applicable.

Definition SemaCast.cpp:37

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

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

Definition SemaCast.cpp:1045

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

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

Definition SemaCast.cpp:3408

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

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

Definition SemaCast.cpp:1838

static void DiagnoseCallingConvCast(Sema &Self, const ExprResult &SrcExpr, QualType DstType, CastOperation::OpRangeType OpRange)

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

Definition SemaCast.cpp:2140

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

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

Definition SemaCast.cpp:1388

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

Definition SemaCast.cpp:2121

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

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

Definition SemaCast.cpp:2972

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

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

Definition SemaCast.cpp:1906

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

Definition SemaCast.cpp:2255

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

Try to diagnose a failed overloaded cast.

Definition SemaCast.cpp:460

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

Diagnose a failed cast.

Definition SemaCast.cpp:574

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

Unwrap one level of types for CastsAwayConstness.

Definition SemaCast.cpp:639

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

Definition SemaCast.cpp:2229

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

Definition SemaCast.cpp:2635

This file declares semantic analysis for HLSL constructs.

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

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.

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

const RecordType * getDetectedVirtual() const

The virtual base discovered on the path (if we are merely detecting virtuals).

bool isRecordingPaths() const

Whether we are recording paths.

void setRecordingPaths(bool RP)

Specify whether we should be recording paths or not.

void clear()

Clear the base-paths results.

std::list< CXXBasePath >::const_iterator const_paths_iterator

bool isAmbiguous(CanQualType BaseType) const

Determine whether the path from the most-derived type to the given base type is ambiguous (i....

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.

CXXRecordDecl * getDefinition() const

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 isInvalidType() const

bool isFixed() const

Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...

This represents one expression.

bool isIntegerConstantExpr(const ASTContext &Ctx) const

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.

@ NPC_NeverValueDependent

Specifies that the expression should never be value-dependent.

ExprObjectKind getObjectKind() const

getObjectKind - The object kind that this expression produces.

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(SourceLocation StartLoc, SourceRange ParenRange, 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.

bool isMemberFunctionPointer() const

Returns true if the member type (i.e.

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

Base for LValueReferenceType and RValueReferenceType.

QualType getPointeeType() const

PartialDiagnostic PDiag(unsigned DiagID=0)

Build a partial diagnostic.

SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)

Emit a 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)

Definition SemaCast.cpp:3472

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

Definition SemaCast.cpp:438

FPOptionsOverride CurFPFeatureOverrides()

bool ShouldSplatAltivecScalarInCast(const VectorType *VecTy)

Definition SemaCast.cpp:2721

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

Definition SemaCast.cpp:426

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)

Definition SemaCast.cpp:3444

ReferenceConversionsScope::ReferenceConversions ReferenceConversions

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.

Definition SemaCast.cpp:314

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)

Definition SemaCast.cpp:2067

TypeSourceInfo * GetTypeForDeclaratorCast(Declarator &D, QualType FromTy)

DiagnosticsEngine & Diags

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

Definition SemaCast.cpp:337

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

Definition SemaCast.cpp:2734

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.

bool isBlockPointerType() const

bool isBooleanType() const

bool isFunctionReferenceType() 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

CXXRecordDecl * getAsCXXRecordDecl() const

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

bool isConstantArrayType() const

RecordDecl * getAsRecordDecl() const

Retrieves the RecordDecl this type refers to.

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

EnumDecl * castAsEnumDecl() 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.

const T * getAsCanonical() const

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

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

Represents a GCC generic vector type.

unsigned getNumElements() const

VectorKind getVectorKind() const

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

CanQual< Type > CanQualType

Represents a canonical, potentially-qualified type.

bool isa(CodeGen::Address addr)

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.

const FunctionProtoType * T

CastKind

CastKind - The kind of operation required for a conversion.

std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt

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

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.

SmallVector< CXXBaseSpecifier *, 4 > CXXCastPath

A simple array of base specifiers.

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

Insertion operator for diagnostics.

CallingConv

CallingConv - Specifies the calling convention that a function uses.

@ AltiVecBool

is AltiVec 'vector bool ...'

@ AltiVecVector

is AltiVec vector

@ AltiVecPixel

is AltiVec 'vector Pixel'

U cast(CodeGen::Address addr)

@ None

The alignment was not explicit in code.

@ Enum

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

ActionResult< Expr * > ExprResult

@ 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