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

1

2

3

4

5

6

7

8

9

10

11

12

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

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

41#include "llvm/ADT/STLExtras.h"

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

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

44

45using namespace clang;

46using namespace sema;

47

63

64

69

71 bool HasLeadingEmptyMacro) {

72 return new (Context) NullStmt(SemiLoc, HasLeadingEmptyMacro);

73}

74

84

87

88

89

91 return;

92

94 if (decl || decl->isInvalidDecl())

95 return;

96

97

99 if (!var) {

100 Diag(decl->getLocation(), diag::err_non_variable_decl_in_for);

101 decl->setInvalidDecl();

102 return;

103 }

104

105

106

107 var->setInit(nullptr);

108

109

110

111

114

115

116

117

119

120 var->setType(type.withConst());

121 var->setARCPseudoStrong(true);

122 }

123 }

124}

125

126

127

128

129

130

133 bool CanAssign;

134 enum { Equality, Inequality, Relational, ThreeWay } Kind;

135

136 if (const BinaryOperator *Op = dyn_cast(E)) {

137 if (!Op->isComparisonOp())

138 return false;

139

140 if (Op->getOpcode() == BO_EQ)

141 Kind = Equality;

142 else if (Op->getOpcode() == BO_NE)

143 Kind = Inequality;

144 else if (Op->getOpcode() == BO_Cmp)

145 Kind = ThreeWay;

146 else {

147 assert(Op->isRelationalOp());

148 Kind = Relational;

149 }

150 Loc = Op->getOperatorLoc();

151 CanAssign = Op->getLHS()->IgnoreParenImpCasts()->isLValue();

152 } else if (const CXXOperatorCallExpr *Op = dyn_cast(E)) {

153 switch (Op->getOperator()) {

154 case OO_EqualEqual:

155 Kind = Equality;

156 break;

157 case OO_ExclaimEqual:

158 Kind = Inequality;

159 break;

160 case OO_Less:

161 case OO_Greater:

162 case OO_GreaterEqual:

163 case OO_LessEqual:

164 Kind = Relational;

165 break;

166 case OO_Spaceship:

167 Kind = ThreeWay;

168 break;

169 default:

170 return false;

171 }

172

173 Loc = Op->getOperatorLoc();

174 CanAssign = Op->getArg(0)->IgnoreParenImpCasts()->isLValue();

175 } else {

176

177 return false;

178 }

179

180

181

183 return false;

184

185 S.Diag(Loc, diag::warn_unused_comparison)

187

188

189

190 if (CanAssign) {

191 if (Kind == Inequality)

192 S.Diag(Loc, diag::note_inequality_comparison_to_or_assign)

194 else if (Kind == Equality)

195 S.Diag(Loc, diag::note_equality_comparison_to_assign)

197 }

198

199 return true;

200}

201

205 if (!A)

206 return false;

207 StringRef Msg = A->getMessage();

208

209 if (Msg.empty()) {

210 if (OffendingDecl)

211 return S.Diag(Loc, diag::warn_unused_return_type)

212 << IsCtor << A << OffendingDecl << false << R1 << R2;

213 if (IsCtor)

214 return S.Diag(Loc, diag::warn_unused_constructor)

215 << A << false << R1 << R2;

216 return S.Diag(Loc, diag::warn_unused_result) << A << false << R1 << R2;

217 }

218

219 if (OffendingDecl)

220 return S.Diag(Loc, diag::warn_unused_return_type)

221 << IsCtor << A << OffendingDecl << true << Msg << R1 << R2;

222 if (IsCtor)

223 return S.Diag(Loc, diag::warn_unused_constructor)

224 << A << true << Msg << R1 << R2;

225 return S.Diag(Loc, diag::warn_unused_result) << A << true << Msg << R1 << R2;

226}

227

228namespace {

229

230

231

232

233

234void DiagnoseUnused(Sema &S, const Expr *E, std::optional DiagID) {

235 bool NoDiscardOnly = !DiagID.has_value();

236

237

238

240 return;

241

243

244

245

246

247

250

251 const Expr *WarnExpr;

255 return;

256

257 if (!NoDiscardOnly) {

258

259

260

261

263 return;

264

265

266

267

271 return;

272 }

273 }

274

275

276

277

278 if (const FullExpr *Temps = dyn_cast(E))

279 E = Temps->getSubExpr();

280 if (const CXXBindTemporaryExpr *TempExpr = dyn_cast(E))

281 E = TempExpr->getSubExpr();

282

284 return;

285

286 E = WarnExpr;

287 if (const auto *Cast = dyn_cast(E))

288 if (Cast->getCastKind() == CK_NoOp ||

289 Cast->getCastKind() == CK_ConstructorConversion ||

290 Cast->getCastKind() == CK_IntegralCast)

291 E = Cast->getSubExpr()->IgnoreImpCasts();

292

293 if (const CallExpr *CE = dyn_cast(E)) {

295 return;

296

297 auto [OffendingDecl, A] = CE->getUnusedResultAttr(S.Context);

299 false))

300 return;

301

302

303

304

305

306 if (const Decl *FD = CE->getCalleeDecl()) {

307 if (ShouldSuppress)

308 return;

309 if (FD->hasAttr()) {

310 S.Diag(Loc, diag::warn_unused_call) << R1 << R2 << "pure";

311 return;

312 }

313 if (FD->hasAttr()) {

314 S.Diag(Loc, diag::warn_unused_call) << R1 << R2 << "const";

315 return;

316 }

317 }

318 } else if (const auto *CE = dyn_cast(E)) {

319 auto [OffendingDecl, A] = CE->getUnusedResultAttr(S.Context);

321 true))

322 return;

323 } else if (const auto *ILE = dyn_cast(E)) {

324 if (const TagDecl *TD = ILE->getType()->getAsTagDecl()) {

325

326 if (DiagnoseNoDiscard(S, TD, TD->getAttr(), Loc, R1,

327 R2, false))

328 return;

329 }

330 } else if (ShouldSuppress)

331 return;

332

333 E = WarnExpr;

334 if (const ObjCMessageExpr *ME = dyn_cast(E)) {

335 if (S.getLangOpts().ObjCAutoRefCount && ME->isDelegateInitCall()) {

336 S.Diag(Loc, diag::err_arc_unused_init_message) << R1;

337 return;

338 }

339

340 auto [OffendingDecl, A] = ME->getUnusedResultAttr(S.Context);

342 false))

343 return;

344 } else if (const PseudoObjectExpr *POE = dyn_cast(E)) {

345 const Expr *Source = POE->getSyntacticForm();

346

348 POE->getNumSemanticExprs() == 1 &&

350 return DiagnoseUnused(S, POE->getSemanticExpr(0), DiagID);

352 DiagID = diag::warn_unused_container_subscript_expr;

354 DiagID = diag::warn_unused_property_expr;

356 = dyn_cast(E)) {

357 const Expr *E = FC->getSubExpr();

359 E = TE->getSubExpr();

361 return;

362 if (const CXXConstructExpr *CE = dyn_cast(E))

363 if (const CXXRecordDecl *RD = CE->getType()->getAsCXXRecordDecl())

364 if (!RD->getAttr())

365 return;

366 }

367

368 if (NoDiscardOnly)

369 return;

370

371

372 if (const CStyleCastExpr *CE = dyn_cast(E)) {

375

376

379

380 S.Diag(Loc, diag::warn_unused_voidptr)

382 return;

383 }

384 }

385

386

387

390 S.Diag(Loc, diag::warn_unused_volatile) << R1 << R2;

391 return;

392 }

393

394

395

396

397 if (DiagID == diag::warn_unused_comma_left_operand && S.isSFINAEContext())

398 return;

399

401 S.PDiag(*DiagID) << R1 << R2);

402}

403}

404

406 if (const LabelStmt *Label = dyn_cast_if_present(S))

407 S = Label->getSubStmt();

408

409 const Expr *E = dyn_cast_if_present(S);

410 if (!E)

411 return;

412

413 DiagnoseUnused(*this, E, DiagID);

414}

415

419

423 assert(FSI);

425 }

426}

427

431

435

438 const unsigned NumElts = Elts.size();

439

440

441

442

443 const unsigned MixedDeclsCodeID = getLangOpts().C99

444 ? diag::warn_mixed_decls_code

445 : diag::ext_mixed_decls_code;

447

448 unsigned i = 0;

449

450 for (; i != NumElts && isa(Elts[i]); ++i)

451 ;

452

453

454 for (; i != NumElts && isa<DeclStmt>(Elts[i]); ++i)

455 ;

456

457 if (i != NumElts) {

460 }

461 }

462

463

464

465

468 for (unsigned i = 0; i != NumElts - 1; ++i)

470 }

471

472

473

474

475

480

482}

483

486 if (!Val.get())

487 return Val;

488

491

492

493

497

498 Expr *CondExpr =

500 if (!CondExpr)

503

504 auto CheckAndFinish = [&](Expr *E) {

507

509

510

511 llvm::APSInt TempVal;

514 }

515

525 return ER;

526 };

527

528 return CheckAndFinish(Val.get());

529}

530

535 assert((LHSVal.isInvalid() || LHSVal.get()) && "missing LHS value");

538 "missing RHS value");

539

541 Diag(CaseLoc, diag::err_case_not_in_switch);

543 }

544

548 }

549

552 Diag(CaseLoc, diag::err_acc_branch_in_out_compute_construct)

553 << 0 << 1;

555 }

556

558 CaseLoc, DotDotDotLoc, ColonLoc);

560 return CS;

561}

562

566

569 Stmt *SubStmt, Scope *CurScope) {

571 Diag(DefaultLoc, diag::err_default_not_in_switch);

572 return SubStmt;

573 }

574

577 Diag(DefaultLoc, diag::err_acc_branch_in_out_compute_construct)

578 << 0 << 1;

580 }

581

584 return DS;

585}

586

590

591 if (TheDecl->getStmt()) {

592 Diag(IdentLoc, diag::err_redefinition_of_label) << TheDecl->getDeclName();

593 Diag(TheDecl->getLocation(), diag::note_previous_definition);

594 return SubStmt;

595 }

596

599 Context.getSourceManager().isInSystemHeader(IdentLoc))

600 Diag(IdentLoc, diag::warn_reserved_extern_symbol)

601 << TheDecl << static_cast(Status);

602

603

604

605 if (getCurScope()->isInOpenACCComputeConstructScope())

607

608

609

610

611

613 Diag(SubStmt->getBeginLoc(), diag::err_acc_update_as_body) << 4;

615 }

616

617

623

624

626 }

627 }

628 return LS;

629}

630

633 Stmt *SubStmt) {

634

635

636 for (const auto *A : Attrs) {

637 if (A->getKind() == attr::MustTail) {

639 return SubStmt;

640 }

642 }

643 }

644

646}

647

649 Stmt *SubStmt) {

652 if (!SemanticAttrs.empty())

654

655

656

657 return SubStmt;

658}

659

663

665

666 return true;

667

668 if (!checkMustTailAttr(St, MTA))

669 return false;

670

671

672

673

674 auto IgnoreImplicitAsWritten = [](Expr *E) -> Expr * {

677 };

678

679

680

681 R->setRetValue(IgnoreImplicitAsWritten(E));

682 return true;

683}

684

685bool Sema::checkMustTailAttr(const Stmt *St, const Attr &MTA) {

687 "musttail cannot be checked from a dependent context");

688

689

690 auto IgnoreParenImplicitAsWritten = [](const Expr *E) -> const Expr * {

694 };

695

697 const auto *CE = dyn_cast_or_null(IgnoreParenImplicitAsWritten(E));

698

699 if (!CE) {

700 Diag(St->getBeginLoc(), diag::err_musttail_needs_call) << &MTA;

701 return false;

702 }

703

704 if (const FunctionDecl *CalleeDecl = CE->getDirectCallee();

705 CalleeDecl && CalleeDecl->hasAttr()) {

706 Diag(St->getBeginLoc(), diag::err_musttail_mismatch) << true << CalleeDecl;

707 Diag(CalleeDecl->getLocation(), diag::note_musttail_disabled_by_not_tail_called);

708 return false;

709 }

710

711 if (const auto *EWC = dyn_cast(E)) {

712 if (EWC->cleanupsHaveSideEffects()) {

713 Diag(St->getBeginLoc(), diag::err_musttail_needs_trivial_args) << &MTA;

714 return false;

715 }

716 }

717

718

719

720 struct FuncType {

721 enum {

722 ft_non_member,

723 ft_static_member,

724 ft_non_static_member,

725 ft_pointer_to_member,

726 } MemberType = ft_non_member;

727

728 QualType This;

729 const FunctionProtoType *Func;

730 const CXXMethodDecl *Method = nullptr;

731 } CallerType, CalleeType;

732

733 auto GetMethodType = [this, St, MTA](const CXXMethodDecl *CMD, FuncType &Type,

734 bool IsCallee) -> bool {

736 Diag(St->getBeginLoc(), diag::err_musttail_structors_forbidden)

737 << IsCallee << isa(CMD);

738 if (IsCallee)

739 Diag(CMD->getBeginLoc(), diag::note_musttail_structors_forbidden)

741 Diag(MTA.getLocation(), diag::note_tail_call_required) << &MTA;

742 return false;

743 }

744 if (CMD->isStatic())

745 Type.MemberType = FuncType::ft_static_member;

746 else {

747 Type.This = CMD->getFunctionObjectParameterType();

748 Type.MemberType = FuncType::ft_non_static_member;

749 }

750 Type.Func = CMD->getType()->castAs();

751 return true;

752 };

753

754 const auto *CallerDecl = dyn_cast(CurContext);

755

756

757 if (!CallerDecl) {

758 int ContextType;

760 ContextType = 0;

762 ContextType = 1;

763 else

764 ContextType = 2;

765 Diag(St->getBeginLoc(), diag::err_musttail_forbidden_from_this_context)

766 << &MTA << ContextType;

767 return false;

768 } else if (const auto *CMD = dyn_cast(CurContext)) {

769

770 if (!GetMethodType(CMD, CallerType, false))

771 return false;

772 } else {

773

774 CallerType.Func = CallerDecl->getType()->getAs();

775 }

776

777 const Expr *CalleeExpr = CE->getCallee()->IgnoreParens();

778 const auto *CalleeBinOp = dyn_cast(CalleeExpr);

779 SourceLocation CalleeLoc = CE->getCalleeDecl()

780 ? CE->getCalleeDecl()->getBeginLoc()

782

783

784 if (const CXXMethodDecl *CMD =

785 dyn_cast_or_null(CE->getCalleeDecl())) {

786

787 if (!GetMethodType(CMD, CalleeType, true))

788 return false;

789 } else if (CalleeBinOp && CalleeBinOp->isPtrMemOp()) {

790

791 const auto *MPT =

792 CalleeBinOp->getRHS()->getType()->castAs();

793 CalleeType.This =

794 Context.getCanonicalTagType(MPT->getMostRecentCXXRecordDecl());

795 CalleeType.Func = MPT->getPointeeType()->castAs();

796 CalleeType.MemberType = FuncType::ft_pointer_to_member;

798 Diag(St->getBeginLoc(), diag::err_musttail_structors_forbidden)

799 << 1 << 1;

800 Diag(MTA.getLocation(), diag::note_tail_call_required) << &MTA;

801 return false;

802 } else {

803

804 CalleeType.Func =

806 }

807

808

809 if (!CalleeType.Func || !CallerType.Func) {

810 Diag(St->getBeginLoc(), diag::err_musttail_needs_prototype) << &MTA;

811 if (!CalleeType.Func && CE->getDirectCallee()) {

812 Diag(CE->getDirectCallee()->getBeginLoc(),

813 diag::note_musttail_fix_non_prototype);

814 }

815 if (!CallerType.Func)

816 Diag(CallerDecl->getBeginLoc(), diag::note_musttail_fix_non_prototype);

817 return false;

818 }

819

820

821

822

823

824

825

826

827 if (CallerType.Func->getCallConv() != CalleeType.Func->getCallConv()) {

828 if (const auto *ND = dyn_cast_or_null(CE->getCalleeDecl()))

829 Diag(St->getBeginLoc(), diag::err_musttail_callconv_mismatch)

830 << true << ND->getDeclName();

831 else

832 Diag(St->getBeginLoc(), diag::err_musttail_callconv_mismatch) << false;

833 Diag(CalleeLoc, diag::note_musttail_callconv_mismatch)

836 Diag(MTA.getLocation(), diag::note_tail_call_required) << &MTA;

837 return false;

838 }

839

840 if (CalleeType.Func->isVariadic() || CallerType.Func->isVariadic()) {

841 Diag(St->getBeginLoc(), diag::err_musttail_no_variadic) << &MTA;

842 return false;

843 }

844

845 const auto *CalleeDecl = CE->getCalleeDecl();

846 if (CalleeDecl && CalleeDecl->hasAttr()) {

847 Diag(St->getBeginLoc(), diag::err_musttail_no_return) << &MTA;

848 return false;

849 }

850

851

852 if (CallerType.This.isNull() != CalleeType.This.isNull()) {

853 if (const auto *ND = dyn_cast_or_null(CE->getCalleeDecl())) {

854 Diag(St->getBeginLoc(), diag::err_musttail_member_mismatch)

855 << CallerType.MemberType << CalleeType.MemberType << true

856 << ND->getDeclName();

857 Diag(CalleeLoc, diag::note_musttail_callee_defined_here)

858 << ND->getDeclName();

859 } else

860 Diag(St->getBeginLoc(), diag::err_musttail_member_mismatch)

861 << CallerType.MemberType << CalleeType.MemberType << false;

862 Diag(MTA.getLocation(), diag::note_tail_call_required) << &MTA;

863 return false;

864 }

865

866 auto CheckTypesMatch = [this](FuncType CallerType, FuncType CalleeType,

867 PartialDiagnostic &PD) -> bool {

868 enum {

873 };

874

875 auto DoTypesMatch = [this, &PD](QualType A, QualType B,

876 unsigned Select) -> bool {

877 if (Context.hasSimilarType(A, B)) {

879 return false;

880 }

881 return true;

882 };

883

884 if (!CallerType.This.isNull() &&

886 return false;

887

888 if (!DoTypesMatch(CallerType.Func->getReturnType(),

890 return false;

891

892 if (CallerType.Func->getNumParams() != CalleeType.Func->getNumParams()) {

894 << CalleeType.Func->getNumParams();

895 return false;

896 }

897

898 ArrayRef CalleeParams = CalleeType.Func->getParamTypes();

899 ArrayRef CallerParams = CallerType.Func->getParamTypes();

900 size_t N = CallerType.Func->getNumParams();

901 for (size_t I = 0; I < N; I++) {

902 if (!DoTypesMatch(CalleeParams[I], CallerParams[I],

904 PD << static_cast(I) + 1;

905 return false;

906 }

907 }

908

909 return true;

910 };

911

912 PartialDiagnostic PD = PDiag(diag::note_musttail_mismatch);

913 if (!CheckTypesMatch(CallerType, CalleeType, PD)) {

914 if (const auto *ND = dyn_cast_or_null(CE->getCalleeDecl()))

916 << true << ND->getDeclName();

917 else

918 Diag(St->getBeginLoc(), diag::err_musttail_mismatch) << false;

919 Diag(CalleeLoc, PD);

920 Diag(MTA.getLocation(), diag::note_tail_call_required) << &MTA;

921 return false;

922 }

923

924

925

926

927 for (auto ArgExpr : CE->arguments()) {

929 Context, ArgExpr->getType(), false);

931 }

932

933 return true;

934}

935

936namespace {

938 typedef EvaluatedExprVisitor Inherited;

939 Sema &SemaRef;

940public:

941 CommaVisitor(Sema &SemaRef) : Inherited(SemaRef.Context), SemaRef(SemaRef) {}

942 void VisitBinaryOperator(BinaryOperator *E) {

945 EvaluatedExprVisitor::VisitBinaryOperator(E);

946 }

947};

948}

949

955 Stmt *elseStmt) {

956 if (Cond.isInvalid())

958

959 bool ConstevalOrNegatedConsteval =

962

963 Expr *CondExpr = Cond.get().second;

964 assert((CondExpr || ConstevalOrNegatedConsteval) &&

965 "If statement: missing condition");

966

968 Diags.isIgnored(diag::warn_comma_operator, CondExpr->getExprLoc()))

969 CommaVisitor(*this).Visit(CondExpr);

970

971 if (!ConstevalOrNegatedConsteval && !elseStmt)

973

974 if (ConstevalOrNegatedConsteval ||

976 auto DiagnoseLikelihood = [&](const Stmt *S) {

978 Diags.Report(A->getLocation(),

979 diag::warn_attribute_has_no_effect_on_compile_time_if)

980 << A << ConstevalOrNegatedConsteval << A->getRange();

981 Diags.Report(IfLoc,

982 diag::note_attribute_has_no_effect_on_compile_time_if_here)

983 << ConstevalOrNegatedConsteval

984 << SourceRange(IfLoc, (ConstevalOrNegatedConsteval

986 : LParenLoc)

988 }

989 };

990 DiagnoseLikelihood(thenStmt);

991 DiagnoseLikelihood(elseStmt);

992 } else {

993 std::tuple<bool, const Attr *, const Attr *> LHC =

995 if (std::get<0>(LHC)) {

996 const Attr *ThenAttr = std::get<1>(LHC);

997 const Attr *ElseAttr = std::get<2>(LHC);

999 diag::warn_attributes_likelihood_ifstmt_conflict)

1000 << ThenAttr << ThenAttr->getRange();

1001 Diags.Report(ElseAttr->getLocation(), diag::note_conflicting_attribute)

1002 << ElseAttr << ElseAttr->getRange();

1003 }

1004 }

1005

1006 if (ConstevalOrNegatedConsteval) {

1009 if (CurContext->isFunctionOrMethod()) {

1010 const auto *FD =

1012 if (FD && FD->isImmediateFunction())

1013 Immediate = true;

1014 }

1016 Diags.Report(IfLoc, diag::warn_consteval_if_always_true) << Immediate;

1017 }

1018

1019

1020

1021

1022

1024 Diag(thenStmt->getBeginLoc(), diag::err_acc_update_as_body) << 0;

1026 }

1027

1028 return BuildIfStmt(IfLoc, StatementKind, LParenLoc, InitStmt, Cond, RParenLoc,

1029 thenStmt, ElseLoc, elseStmt);

1030}

1031

1037 Stmt *elseStmt) {

1038 if (Cond.isInvalid())

1040

1044

1046 Cond.get().first, Cond.get().second, LParenLoc,

1047 RParenLoc, thenStmt, ElseLoc, elseStmt);

1048}

1049

1050namespace {

1051 struct CaseCompareFunctor {

1052 bool operator()(const std::pair<llvm::APSInt, CaseStmt*> &LHS,

1053 const llvm::APSInt &RHS) {

1054 return LHS.first < RHS;

1055 }

1056 bool operator()(const std::pair<llvm::APSInt, CaseStmt*> &LHS,

1057 const std::pair<llvm::APSInt, CaseStmt*> &RHS) {

1058 return LHS.first < RHS.first;

1059 }

1060 bool operator()(const llvm::APSInt &LHS,

1061 const std::pair<llvm::APSInt, CaseStmt*> &RHS) {

1062 return LHS < RHS.first;

1063 }

1064 };

1065}

1066

1067

1068

1069static bool CmpCaseVals(const std::pair<llvm::APSInt, CaseStmt*>& lhs,

1070 const std::pair<llvm::APSInt, CaseStmt*>& rhs) {

1071 if (lhs.first < rhs.first)

1072 return true;

1073

1074 if (lhs.first == rhs.first &&

1075 lhs.second->getCaseLoc() < rhs.second->getCaseLoc())

1076 return true;

1077 return false;

1078}

1079

1080

1081

1082static bool CmpEnumVals(const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,

1083 const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)

1084{

1085 return lhs.first < rhs.first;

1086}

1087

1088

1089

1090static bool EqEnumVals(const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,

1091 const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)

1092{

1093 return lhs.first == rhs.first;

1094}

1095

1096

1097

1099 if (const auto *FE = dyn_cast(E))

1100 E = FE->getSubExpr();

1101 while (const auto *ImpCast = dyn_cast(E)) {

1102 if (ImpCast->getCastKind() != CK_IntegralCast) break;

1103 E = ImpCast->getSubExpr();

1104 }

1106}

1107

1111

1112 public:

1113 SwitchConvertDiagnoser(Expr *Cond)

1116

1119 return S.Diag(Loc, diag::err_typecheck_statement_requires_integer) << T;

1120 }

1121

1124 return S.Diag(Loc, diag::err_switch_incomplete_class_type)

1125 << T << Cond->getSourceRange();

1126 }

1127

1130 return S.Diag(Loc, diag::err_switch_explicit_conversion) << T << ConvTy;

1131 }

1132

1135 return S.Diag(Conv->getLocation(), diag::note_switch_conversion)

1137 }

1138

1141 return S.Diag(Loc, diag::err_switch_multiple_conversions) << T;

1142 }

1143

1146 return S.Diag(Conv->getLocation(), diag::note_switch_conversion)

1148 }

1149

1152 llvm_unreachable("conversion functions are permitted");

1153 }

1154 } SwitchDiagnoser(Cond);

1155

1160

1161

1162

1163 Cond = CondResult.get();

1164 if (Cond->isTypeDependent() &&

1165 Cond->getType()->isIntegralOrEnumerationType())

1167

1168

1170}

1171

1176 Expr *CondExpr = Cond.get().second;

1177 assert((Cond.isInvalid() || CondExpr) && "switch with no condition");

1178

1180

1181

1182

1183

1187

1188

1189

1190 Diag(SwitchLoc, diag::warn_bool_switch_condition)

1192 }

1193 }

1194

1196

1198 LParenLoc, RParenLoc);

1201 return SS;

1202}

1203

1204static void AdjustAPSInt(llvm::APSInt &Val, unsigned BitWidth, bool IsSigned) {

1205 Val = Val.extOrTrunc(BitWidth);

1206 Val.setIsSigned(IsSigned);

1207}

1208

1209

1210

1212 unsigned UnpromotedWidth, bool UnpromotedSign) {

1213

1215 return;

1216

1217

1218

1219

1220 if (UnpromotedWidth < Val.getBitWidth()) {

1221 llvm::APSInt ConvVal(Val);

1222 AdjustAPSInt(ConvVal, UnpromotedWidth, UnpromotedSign);

1223 AdjustAPSInt(ConvVal, Val.getBitWidth(), Val.isSigned());

1224

1225

1226

1227 if (ConvVal != Val)

1228 S.Diag(Loc, diag::warn_case_value_overflow) << toString(Val, 10)

1230 }

1231}

1232

1234

1235

1236

1239 const Expr *CaseExpr,

1240 EnumValsTy::iterator &EI,

1241 EnumValsTy::iterator &EIEnd,

1242 const llvm::APSInt &Val) {

1244 return false;

1245

1248 if (const VarDecl *VD = dyn_cast(DRE->getDecl())) {

1249 QualType VarType = VD->getType();

1253 return false;

1254 }

1255 }

1256

1257 if (ED->hasAttr())

1259

1260 while (EI != EIEnd && EI->first < Val)

1261 EI++;

1262

1263 if (EI != EIEnd && EI->first == Val)

1264 return false;

1265

1266 return true;

1267}

1268

1270 const Expr *Case) {

1273

1274 const EnumType *CondEnumType = CondType->getAsCanonical();

1275 const EnumType *CaseEnumType = CaseType->getAsCanonical();

1276 if (!CondEnumType || !CaseEnumType)

1277 return;

1278

1279

1280 if (!CondEnumType->getDecl()->getIdentifier() &&

1281 !CondEnumType->getDecl()->getTypedefNameForAnonDecl())

1282 return;

1283 if (!CaseEnumType->getDecl()->getIdentifier() &&

1284 !CaseEnumType->getDecl()->getTypedefNameForAnonDecl())

1285 return;

1286

1288 return;

1289

1290 S.Diag(Case->getExprLoc(), diag::warn_comparison_of_mixed_enum_types_switch)

1291 << CondType << CaseType << Cond->getSourceRange()

1293}

1294

1297 Stmt *BodyStmt) {

1300 assert(SS == getCurFunction()->SwitchStack.back().getPointer() &&

1301 "switch stack missing push/pop!");

1302

1304

1305 if (!BodyStmt) return StmtError();

1306

1307

1308

1309

1310

1312 Diag(BodyStmt->getBeginLoc(), diag::err_acc_update_as_body) << 3;

1314 }

1315

1316 SS->setBody(BodyStmt, SwitchLoc);

1317

1319 if (!CondExpr) return StmtError();

1320

1322

1323

1324

1325

1326

1327

1328

1329

1330 const Expr *CondExprBeforePromotion = CondExpr;

1331 QualType CondTypeBeforePromotion =

1333

1334

1335

1336 bool HasDependentValue

1338 unsigned CondWidth = HasDependentValue ? 0 : Context.getIntWidth(CondType);

1340

1341

1342

1343

1344

1345 unsigned CondWidthBeforePromotion

1346 = HasDependentValue ? 0 : Context.getIntWidth(CondTypeBeforePromotion);

1347 bool CondIsSignedBeforePromotion

1349

1350

1351

1352

1354 CaseValsTy CaseVals;

1355

1356

1357 typedef std::vector<std::pair<llvm::APSInt, CaseStmt*> > CaseRangesTy;

1358 CaseRangesTy CaseRanges;

1359

1361

1362 bool CaseListIsErroneous = false;

1363

1364

1365

1366

1368 SC = SC->getNextSwitchCase()) {

1369

1370 if (DefaultStmt *DS = dyn_cast(SC)) {

1371 if (TheDefaultStmt) {

1372 Diag(DS->getDefaultLoc(), diag::err_multiple_default_labels_defined);

1373 Diag(TheDefaultStmt->getDefaultLoc(), diag::note_duplicate_case_prev);

1374

1375

1376

1377

1378

1379 CaseListIsErroneous = true;

1380 }

1381 TheDefaultStmt = DS;

1382

1383 } else {

1385

1387

1389 HasDependentValue = true;

1390 break;

1391 }

1392

1393

1394

1395 const Expr *LoBeforePromotion = Lo;

1398

1399

1400

1402 CondIsSignedBeforePromotion);

1403

1404

1406 LoBeforePromotion);

1407

1408

1409 AdjustAPSInt(LoVal, CondWidth, CondIsSigned);

1410

1411

1414 HasDependentValue = true;

1415 break;

1416 }

1417 CaseRanges.push_back(std::make_pair(LoVal, CS));

1418 } else

1419 CaseVals.push_back(std::make_pair(LoVal, CS));

1420 }

1421 }

1422

1423 if (!HasDependentValue) {

1424

1425

1426 llvm::APSInt ConstantCondValue;

1427 bool HasConstantCond = false;

1428 if (!TheDefaultStmt) {

1432 if (Result.Val.isInt())

1433 ConstantCondValue = Result.Val.getInt();

1434 assert(!HasConstantCond ||

1435 (ConstantCondValue.getBitWidth() == CondWidth &&

1436 ConstantCondValue.isSigned() == CondIsSigned));

1437 Diag(SwitchLoc, diag::warn_switch_default);

1438 }

1439 bool ShouldCheckConstantCond = HasConstantCond;

1440

1441

1442 llvm::stable_sort(CaseVals, CmpCaseVals);

1443

1444 if (!CaseVals.empty()) {

1445 for (unsigned i = 0, e = CaseVals.size(); i != e; ++i) {

1446 if (ShouldCheckConstantCond &&

1447 CaseVals[i].first == ConstantCondValue)

1448 ShouldCheckConstantCond = false;

1449

1450 if (i != 0 && CaseVals[i].first == CaseVals[i-1].first) {

1451

1452

1453 StringRef PrevString, CurrString;

1456 if (DeclRefExpr *DeclRef = dyn_cast(PrevCase)) {

1457 PrevString = DeclRef->getDecl()->getName();

1458 }

1459 if (DeclRefExpr *DeclRef = dyn_cast(CurrCase)) {

1460 CurrString = DeclRef->getDecl()->getName();

1461 }

1463 CaseVals[i-1].first.toString(CaseValStr);

1464

1465 if (PrevString == CurrString)

1466 Diag(CaseVals[i].second->getLHS()->getBeginLoc(),

1467 diag::err_duplicate_case)

1468 << (PrevString.empty() ? CaseValStr.str() : PrevString);

1469 else

1470 Diag(CaseVals[i].second->getLHS()->getBeginLoc(),

1471 diag::err_duplicate_case_differing_expr)

1472 << (PrevString.empty() ? CaseValStr.str() : PrevString)

1473 << (CurrString.empty() ? CaseValStr.str() : CurrString)

1474 << CaseValStr;

1475

1476 Diag(CaseVals[i - 1].second->getLHS()->getBeginLoc(),

1477 diag::note_duplicate_case_prev);

1478

1479

1480 CaseListIsErroneous = true;

1481 }

1482 }

1483 }

1484

1485

1486

1487 if (!CaseRanges.empty()) {

1488

1489

1490 llvm::stable_sort(CaseRanges);

1491

1492

1493 std::vectorllvm::APSInt HiVals;

1494 for (unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {

1495 llvm::APSInt &LoVal = CaseRanges[i].first;

1496 CaseStmt *CR = CaseRanges[i].second;

1498

1499 const Expr *HiBeforePromotion = Hi;

1502

1503

1504

1506 CondWidthBeforePromotion, CondIsSignedBeforePromotion);

1507

1508

1509 AdjustAPSInt(HiVal, CondWidth, CondIsSigned);

1510

1511

1512 if (LoVal > HiVal) {

1515 CaseRanges.erase(CaseRanges.begin()+i);

1516 --i;

1517 --e;

1518 continue;

1519 }

1520

1521 if (ShouldCheckConstantCond &&

1522 LoVal <= ConstantCondValue &&

1523 ConstantCondValue <= HiVal)

1524 ShouldCheckConstantCond = false;

1525

1526 HiVals.push_back(HiVal);

1527 }

1528

1529

1530

1531

1532 for (unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {

1533 llvm::APSInt &CRLo = CaseRanges[i].first;

1534 llvm::APSInt &CRHi = HiVals[i];

1535 CaseStmt *CR = CaseRanges[i].second;

1536

1537

1538

1539 CaseStmt *OverlapStmt = nullptr;

1540 llvm::APSInt OverlapVal(32);

1541

1542

1543

1544 CaseValsTy::iterator I =

1545 llvm::lower_bound(CaseVals, CRLo, CaseCompareFunctor());

1546 if (I != CaseVals.end() && I->first < CRHi) {

1547 OverlapVal = I->first;

1548 OverlapStmt = I->second;

1549 }

1550

1551

1552 I = std::upper_bound(I, CaseVals.end(), CRHi, CaseCompareFunctor());

1553 if (I != CaseVals.begin() && (I-1)->first >= CRLo) {

1554 OverlapVal = (I-1)->first;

1555 OverlapStmt = (I-1)->second;

1556 }

1557

1558

1559

1560 if (i && CRLo <= HiVals[i-1]) {

1561 OverlapVal = HiVals[i-1];

1562 OverlapStmt = CaseRanges[i-1].second;

1563 }

1564

1565 if (OverlapStmt) {

1566

1568 << toString(OverlapVal, 10);

1570 diag::note_duplicate_case_prev);

1571

1572

1573 CaseListIsErroneous = true;

1574 }

1575 }

1576 }

1577

1578

1579 if (!CaseListIsErroneous && !CaseListIsIncomplete &&

1580 ShouldCheckConstantCond) {

1581

1582

1583 Diag(CondExpr->getExprLoc(), diag::warn_missing_case_for_condition)

1584 << toString(ConstantCondValue, 10)

1586 }

1587

1588

1589

1590

1591

1592

1593

1594 if (!CaseListIsErroneous && !CaseListIsIncomplete && !HasConstantCond &&

1596 const auto *ED = CondTypeBeforePromotion->castAsEnumDecl();

1597 if (!ED->isCompleteDefinition() || ED->enumerators().empty())

1598 goto enum_out;

1599

1601

1602

1603

1604 for (auto *EDI : ED->enumerators()) {

1605 llvm::APSInt Val = EDI->getInitVal();

1607 EnumVals.push_back(std::make_pair(Val, EDI));

1608 }

1609 llvm::stable_sort(EnumVals, CmpEnumVals);

1610 auto EI = EnumVals.begin(), EIEnd = llvm::unique(EnumVals, EqEnumVals);

1611

1612

1613 for (CaseValsTy::const_iterator CI = CaseVals.begin();

1614 CI != CaseVals.end(); CI++) {

1615 Expr *CaseExpr = CI->second->getLHS();

1617 CI->first))

1618 Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)

1619 << CondTypeBeforePromotion;

1620 }

1621

1622

1623 EI = EnumVals.begin();

1624 for (CaseRangesTy::const_iterator RI = CaseRanges.begin();

1625 RI != CaseRanges.end(); RI++) {

1626 Expr *CaseExpr = RI->second->getLHS();

1628 RI->first))

1629 Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)

1630 << CondTypeBeforePromotion;

1631

1632 llvm::APSInt Hi =

1633 RI->second->getRHS()->EvaluateKnownConstInt(Context);

1635

1636 CaseExpr = RI->second->getRHS();

1638 Hi))

1639 Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)

1640 << CondTypeBeforePromotion;

1641 }

1642

1643

1644 auto CI = CaseVals.begin();

1645 auto RI = CaseRanges.begin();

1646 bool hasCasesNotInSwitch = false;

1647

1649

1650 for (EI = EnumVals.begin(); EI != EIEnd; EI++) {

1651

1652 switch (EI->second->getAvailability()) {

1654

1655

1656 break;

1657

1659

1660 continue;

1661

1663

1664

1666 break;

1667 }

1668

1669 if (EI->second->hasAttr())

1670 continue;

1671

1672

1673 while (CI != CaseVals.end() && CI->first < EI->first)

1674 CI++;

1675

1676 if (CI != CaseVals.end() && CI->first == EI->first)

1677 continue;

1678

1679

1680 for (; RI != CaseRanges.end(); RI++) {

1681 llvm::APSInt Hi =

1682 RI->second->getRHS()->EvaluateKnownConstInt(Context);

1684 if (EI->first <= Hi)

1685 break;

1686 }

1687

1688 if (RI == CaseRanges.end() || EI->first < RI->first) {

1689 hasCasesNotInSwitch = true;

1690 UnhandledNames.push_back(EI->second->getDeclName());

1691 }

1692 }

1693

1694 if (TheDefaultStmt && UnhandledNames.empty() && ED->isClosedNonFlag())

1695 Diag(TheDefaultStmt->getDefaultLoc(), diag::warn_unreachable_default);

1696

1697

1698 if (!UnhandledNames.empty()) {

1699 auto DB = Diag(CondExpr->getExprLoc(), TheDefaultStmt

1700 ? diag::warn_def_missing_case

1701 : diag::warn_missing_case)

1702 << CondExpr->getSourceRange() << (int)UnhandledNames.size();

1703

1704 for (size_t I = 0, E = std::min(UnhandledNames.size(), (size_t)3);

1705 I != E; ++I)

1706 DB << UnhandledNames[I];

1707 }

1708

1709 if (!hasCasesNotInSwitch)

1711 }

1712 enum_out:;

1713 }

1714

1715 if (BodyStmt)

1717 diag::warn_empty_switch_body);

1718

1719

1720

1721 if (CaseListIsErroneous)

1723

1724 return SS;

1725}

1726

1727void

1729 Expr *SrcExpr) {

1730

1732 return;

1733

1735 Context.hasSameUnqualifiedType(SrcType, DstType))

1736 return;

1737

1739 return;

1740

1742 if (!ED->isClosed())

1743 return;

1744

1745 if (Diags.isIgnored(diag::warn_not_in_enum_assignment, SrcExpr->getExprLoc()))

1746 return;

1747

1749 if (!RHSVal)

1750 return;

1751

1752

1753 unsigned DstWidth = Context.getIntWidth(DstType);

1755 AdjustAPSInt(*RHSVal, DstWidth, DstIsSigned);

1756

1757 if (ED->hasAttr()) {

1759 Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)

1761 return;

1762 }

1763

1767

1768

1769

1770 for (auto *EDI : ED->enumerators()) {

1771 llvm::APSInt Val = EDI->getInitVal();

1773 EnumVals.emplace_back(Val, EDI);

1774 }

1775 if (EnumVals.empty())

1776 return;

1777 llvm::stable_sort(EnumVals, CmpEnumVals);

1778 EnumValsTy::iterator EIend = llvm::unique(EnumVals, EqEnumVals);

1779

1780

1781 EnumValsTy::const_iterator EI = EnumVals.begin();

1782 while (EI != EIend && EI->first < *RHSVal)

1783 EI++;

1784 if (EI == EIend || EI->first != *RHSVal) {

1785 Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)

1787 }

1788}

1789

1793 if (Cond.isInvalid())

1795

1796 auto CondVal = Cond.get();

1797 CheckBreakContinueBinding(CondVal.second);

1798

1799 if (CondVal.second &&

1800 Diags.isIgnored(diag::warn_comma_operator, CondVal.second->getExprLoc()))

1801 CommaVisitor(*this).Visit(CondVal.second);

1802

1803

1804

1805

1806

1808 Diag(Body->getBeginLoc(), diag::err_acc_update_as_body) << 1;

1810 }

1811

1814

1816 WhileLoc, LParenLoc, RParenLoc);

1817}

1818

1823 assert(Cond && "ActOnDoStmt(): missing expression");

1824

1825 CheckBreakContinueBinding(Cond);

1829 Cond = CondResult.get();

1830

1834 Cond = CondResult.get();

1835

1836

1838 Diags.isIgnored(diag::warn_comma_operator, Cond->getExprLoc()))

1839 CommaVisitor(*this).Visit(Cond);

1840

1841

1842

1843

1844

1846 Diag(Body->getBeginLoc(), diag::err_acc_update_as_body) << 2;

1848 }

1849

1850 return new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen);

1851}

1852

1853namespace {

1854

1856

1857

1858

1859

1861 DeclSetVector &Decls;

1863 bool Simple;

1864 public:

1866

1867 DeclExtractor(Sema &S, DeclSetVector &Decls,

1869 Inherited(S.Context),

1870 Decls(Decls),

1871 Ranges(Ranges),

1872 Simple(true) {}

1873

1874 bool isSimple() { return Simple; }

1875

1876

1877 void VisitMemberExpr(MemberExpr* E) {

1878 Simple = false;

1879 }

1880

1881

1882

1883 void VisitStmt(Stmt *S) { Simple = false; }

1884

1885 void VisitBinaryOperator(BinaryOperator *E) {

1888 }

1889

1890 void VisitCastExpr(CastExpr *E) {

1892 }

1893

1894 void VisitUnaryOperator(UnaryOperator *E) {

1895

1897 Simple = false;

1898 else

1900 }

1901

1902 void VisitConditionalOperator(ConditionalOperator *E) {

1906 }

1907

1908 void VisitParenExpr(ParenExpr *E) {

1910 }

1911

1912 void VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {

1915 }

1916

1917 void VisitIntegerLiteral(IntegerLiteral *E) { }

1918 void VisitFloatingLiteral(FloatingLiteral *E) { }

1919 void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) { }

1920 void VisitCharacterLiteral(CharacterLiteral *E) { }

1921 void VisitGNUNullExpr(GNUNullExpr *E) { }

1922 void VisitImaginaryLiteral(ImaginaryLiteral *E) { }

1923

1924 void VisitDeclRefExpr(DeclRefExpr *E) {

1925 VarDecl *VD = dyn_cast(E->getDecl());

1926 if (!VD) {

1927

1928 Simple = false;

1929 return;

1930 }

1931

1933

1934 Decls.insert(VD);

1935 }

1936

1937 };

1938

1939

1940

1942 DeclSetVector &Decls;

1943 bool FoundDecl;

1944

1945 public:

1946 typedef EvaluatedExprVisitor Inherited;

1947

1948 DeclMatcher(Sema &S, DeclSetVector &Decls, Stmt *Statement) :

1949 Inherited(S.Context), Decls(Decls), FoundDecl(false) {

1950 if (!Statement) return;

1951

1952 Visit(Statement);

1953 }

1954

1955 void VisitReturnStmt(ReturnStmt *S) {

1956 FoundDecl = true;

1957 }

1958

1959 void VisitBreakStmt(BreakStmt *S) {

1960 FoundDecl = true;

1961 }

1962

1963 void VisitGotoStmt(GotoStmt *S) {

1964 FoundDecl = true;

1965 }

1966

1967 void VisitCastExpr(CastExpr *E) {

1968 if (E->getCastKind() == CK_LValueToRValue)

1969 CheckLValueToRValueCast(E->getSubExpr());

1970 else

1972 }

1973

1974 void CheckLValueToRValueCast(Expr *E) {

1976

1978 return;

1979 }

1980

1981 if (ConditionalOperator *CO = dyn_cast(E)) {

1982 Visit(CO->getCond());

1983 CheckLValueToRValueCast(CO->getTrueExpr());

1984 CheckLValueToRValueCast(CO->getFalseExpr());

1985 return;

1986 }

1987

1988 if (BinaryConditionalOperator *BCO =

1989 dyn_cast(E)) {

1990 CheckLValueToRValueCast(BCO->getOpaqueValue()->getSourceExpr());

1991 CheckLValueToRValueCast(BCO->getFalseExpr());

1992 return;

1993 }

1994

1995 Visit(E);

1996 }

1997

1998 void VisitDeclRefExpr(DeclRefExpr *E) {

1999 if (VarDecl *VD = dyn_cast(E->getDecl()))

2000 if (Decls.count(VD))

2001 FoundDecl = true;

2002 }

2003

2004 void VisitPseudoObjectExpr(PseudoObjectExpr *POE) {

2005

2006

2007 for (auto *S : POE->semantics()) {

2008 if (auto *OVE = dyn_cast(S))

2009

2010 Visit(OVE->getSourceExpr());

2011 else

2012 Visit(S);

2013 }

2014 }

2015

2016 bool FoundDeclInUse() { return FoundDecl; }

2017

2018 };

2019

2020 void CheckForLoopConditionalStatement(Sema &S, Expr *Second,

2022

2023 if (!Second) return;

2024

2025 if (S.Diags.isIgnored(diag::warn_variables_not_in_loop_body,

2027 return;

2028

2030 DeclSetVector Decls;

2032 DeclExtractor DE(S, Decls, Ranges);

2033 DE.Visit(Second);

2034

2035

2036 if (!DE.isSimple()) return;

2037

2038

2039 if (Decls.size() == 0) return;

2040

2041

2042 for (auto *VD : Decls)

2044 return;

2045

2046 if (DeclMatcher(S, Decls, Second).FoundDeclInUse() ||

2047 DeclMatcher(S, Decls, Third).FoundDeclInUse() ||

2048 DeclMatcher(S, Decls, Body).FoundDeclInUse())

2049 return;

2050

2051

2052 if (Decls.size() > 4) {

2053 PDiag << 0;

2054 } else {

2055 PDiag << (unsigned)Decls.size();

2056 for (auto *VD : Decls)

2058 }

2059

2060 for (auto Range : Ranges)

2062

2063 S.Diag(Ranges.begin()->getBegin(), PDiag);

2064 }

2065

2066

2067

2068 bool ProcessIterationStmt(Sema &S, Stmt* Statement, bool &Increment,

2070 if (auto Cleanups = dyn_cast(Statement))

2071 if (!Cleanups->cleanupsHaveSideEffects())

2072 Statement = Cleanups->getSubExpr();

2073

2074 if (UnaryOperator *UO = dyn_cast(Statement)) {

2075 switch (UO->getOpcode()) {

2076 default: return false;

2077 case UO_PostInc:

2078 case UO_PreInc:

2079 Increment = true;

2080 break;

2081 case UO_PostDec:

2082 case UO_PreDec:

2083 Increment = false;

2084 break;

2085 }

2086 DRE = dyn_cast(UO->getSubExpr());

2087 return DRE;

2088 }

2089

2094 default: return false;

2095 case OO_PlusPlus:

2096 Increment = true;

2097 break;

2098 case OO_MinusMinus:

2099 Increment = false;

2100 break;

2101 }

2102 DRE = dyn_cast(Call->getArg(0));

2103 return DRE;

2104 }

2105

2106 return false;

2107 }

2108

2109

2110

2112 SourceLocation BreakLoc;

2113 SourceLocation ContinueLoc;

2114 bool InSwitch = false;

2115

2116 public:

2117 BreakContinueFinder(Sema &S, const Stmt* Body) :

2118 Inherited(S.Context) {

2119 Visit(Body);

2120 }

2121

2122 typedef ConstEvaluatedExprVisitor Inherited;

2123

2124 void VisitContinueStmt(const ContinueStmt* E) {

2125 ContinueLoc = E->getKwLoc();

2126 }

2127

2128 void VisitBreakStmt(const BreakStmt* E) {

2129 if (!InSwitch)

2131 }

2132

2133 void VisitSwitchStmt(const SwitchStmt* S) {

2135 Visit(Init);

2137 Visit(CondVar);

2139 Visit(Cond);

2140

2141

2142 InSwitch = true;

2143 if (const Stmt *Body = S->getBody())

2144 Visit(Body);

2145 InSwitch = false;

2146 }

2147

2148 void VisitForStmt(const ForStmt *S) {

2149

2150

2152 Visit(Init);

2153 }

2154

2155 void VisitWhileStmt(const WhileStmt *) {

2156

2157

2158 }

2159

2160 void VisitDoStmt(const DoStmt *) {

2161

2162

2163 }

2164

2165 void VisitCXXForRangeStmt(const CXXForRangeStmt *S) {

2166

2167

2169 Visit(Init);

2171 Visit(Range);

2173 Visit(Begin);

2174 if (const Stmt *End = S->getEndStmt())

2175 Visit(End);

2176 }

2177

2178 void VisitObjCForCollectionStmt(const ObjCForCollectionStmt *S) {

2179

2180

2181 if (const Stmt *Element = S->getElement())

2182 Visit(Element);

2183 if (const Stmt *Collection = S->getCollection())

2184 Visit(Collection);

2185 }

2186

2187 bool ContinueFound() { return ContinueLoc.isValid(); }

2188 bool BreakFound() { return BreakLoc.isValid(); }

2189 SourceLocation GetContinueLoc() { return ContinueLoc; }

2190 SourceLocation GetBreakLoc() { return BreakLoc; }

2191

2192 };

2193

2194

2195

2196

2197

2198

2199 void CheckForRedundantIteration(Sema &S, Expr *Third, Stmt *Body) {

2200

2201 if (!Body || !Third) return;

2202

2203

2204 CompoundStmt *CS = dyn_cast(Body);

2205 if (!CS || CS->body_empty()) return;

2207 if (!LastStmt) return;

2208

2209 if (S.Diags.isIgnored(diag::warn_redundant_loop_iteration,

2211 return;

2212

2213 bool LoopIncrement, LastIncrement;

2215

2216 if (!ProcessIterationStmt(S, Third, LoopIncrement, LoopDRE)) return;

2217 if (!ProcessIterationStmt(S, LastStmt, LastIncrement, LastDRE)) return;

2218

2219

2220

2221 if (LoopIncrement != LastIncrement ||

2223

2224 if (BreakContinueFinder(S, Body).ContinueFound()) return;

2225

2226 S.Diag(LastDRE->getLocation(), diag::warn_redundant_loop_iteration)

2227 << LastDRE->getDecl() << LastIncrement;

2228 S.Diag(LoopDRE->getLocation(), diag::note_loop_iteration_here)

2229 << LoopIncrement;

2230 }

2231

2232}

2233

2234

2235void Sema::CheckBreakContinueBinding(Expr *E) {

2237 return;

2238 BreakContinueFinder BCFinder(*this, E);

2239 Scope *BreakParent = CurScope->getBreakParent();

2240 if (BCFinder.BreakFound() && BreakParent) {

2242 Diag(BCFinder.GetBreakLoc(), diag::warn_break_binds_to_switch);

2243 } else {

2244 Diag(BCFinder.GetBreakLoc(), diag::warn_loop_ctrl_binds_to_inner)

2245 << "break";

2246 }

2247 } else if (BCFinder.ContinueFound() && CurScope->getContinueParent()) {

2248 Diag(BCFinder.GetContinueLoc(), diag::warn_loop_ctrl_binds_to_inner)

2249 << "continue";

2250 }

2251}

2252

2256 Stmt *Body) {

2259

2261 if (DeclStmt *DS = dyn_cast_or_null(First)) {

2262

2263

2264

2265 const Decl *NonVarSeen = nullptr;

2266 bool VarDeclSeen = false;

2267 for (auto *DI : DS->decls()) {

2268 if (VarDecl *VD = dyn_cast(DI)) {

2269 VarDeclSeen = true;

2271 Diag(DI->getLocation(),

2273 ? diag::warn_c17_non_local_variable_decl_in_for

2274 : diag::ext_c23_non_local_variable_decl_in_for);

2275 } else if (!NonVarSeen) {

2276

2277

2278

2279

2280

2281

2282

2284 NonVarSeen = DI;

2285 }

2286 }

2287

2288

2289 if (NonVarSeen && !VarDeclSeen)

2291 getLangOpts().C23 ? diag::warn_c17_non_variable_decl_in_for

2292 : diag::ext_c23_non_variable_decl_in_for);

2293 }

2294 }

2295

2296 CheckBreakContinueBinding(Second.get().second);

2297 CheckBreakContinueBinding(third.get());

2298

2299 if (!Second.get().first)

2300 CheckForLoopConditionalStatement(*this, Second.get().second, third.get(),

2301 Body);

2302 CheckForRedundantIteration(*this, third.get(), Body);

2303

2304 if (Second.get().second &&

2305 Diags.isIgnored(diag::warn_comma_operator,

2306 Second.get().second->getExprLoc()))

2307 CommaVisitor(*this).Visit(Second.get().second);

2308

2312

2315 Body, ForLoc, LParenLoc, RParenLoc);

2316}

2317

2319

2320

2323 E = result.get();

2324

2329}

2330

2331

2332

2335 if (Decl->getType()->isUndeducedType()) {

2339 return true;

2340 }

2342 }

2343

2344

2345

2348 SemaRef.Diag(Loc, DiagID) << Init->getType();

2349 } else {

2352 Decl->getTypeSourceInfo()->getTypeLoc(), Init, InitType, Info);

2355 SemaRef.Diag(Loc, DiagID) << Init->getType();

2356 }

2357

2358 if (InitType.isNull()) {

2360 return true;

2361 }

2362 Decl->setType(InitType);

2363

2364

2365

2366

2367 if (SemaRef.getLangOpts().ObjCAutoRefCount &&

2370

2374 return false;

2375}

2376

2377namespace {

2378

2379

2380enum BeginEndFunction {

2381 BEF_begin,

2382 BEF_end

2383};

2384

2385

2386

2387

2388

2389void NoteForRangeBeginEndFunction(Sema &SemaRef, Expr *E,

2390 BeginEndFunction BEF) {

2391 CallExpr *CE = dyn_cast(E);

2392 if (!CE)

2393 return;

2395 if (!D)

2396 return;

2398

2399 std::string Description;

2400 bool IsTemplate = false;

2404 IsTemplate = true;

2405 }

2406

2407 SemaRef.Diag(Loc, diag::note_for_range_begin_end)

2408 << BEF << IsTemplate << Description << E->getType();

2409}

2410

2411

2420 Decl->setCXXForRangeImplicitVar(true);

2421 return Decl;

2422}

2423

2424}

2425

2430

2436

2439

2441

2442 if (InitStmt)

2443 return Diag(InitStmt->getBeginLoc(), diag::err_objc_for_range_init_stmt)

2446 }

2447

2449 assert(DS && "first part of for range not a decl stmt");

2450

2452 Diag(DS->getBeginLoc(), diag::err_type_defined_in_for_range);

2454 }

2455

2456

2457

2463 }

2464

2465

2466

2471 }

2472 }

2473

2474

2475

2476 const auto DepthStr = std::to_string(S->getDepth() / 2);

2478 VarDecl *RangeVar = BuildForRangeVarDecl(*this, RangeLoc,

2479 Context.getAutoRRefDeductType(),

2480 std::string("__range") + DepthStr);

2482 diag::err_for_range_deduction_failure)) {

2485 }

2486

2487

2494 }

2495

2497 ForLoc, CoawaitLoc, InitStmt, ColonLoc, RangeDecl.get(),

2498 nullptr, nullptr,

2499 nullptr, nullptr, DS, RParenLoc, Kind,

2500 LifetimeExtendTemps);

2504 }

2505

2506 return R;

2507}

2508

2509

2510

2511

2512

2513

2514

2515

2516

2517

2523 ExprResult *EndExpr, BeginEndFunction *BEF) {

2527 ColonLoc);

2528

2529 LookupResult BeginMemberLookup(SemaRef, BeginNameInfo,

2532

2533 auto BuildBegin = [&] {

2534 *BEF = BEF_begin;

2537 BeginMemberLookup, CandidateSet,

2538 BeginRange, BeginExpr);

2539

2542 SemaRef.Diag(BeginRange->getBeginLoc(), diag::note_in_for_range)

2543 << ColonLoc << BEF_begin << BeginRange->getType();

2544 return RangeStatus;

2545 }

2547

2548

2549

2551 BeginExpr->get());

2554 }

2556 diag::err_for_range_iter_deduction_failure)) {

2557 NoteForRangeBeginEndFunction(SemaRef, BeginExpr->get(), *BEF);

2559 }

2561 };

2562

2563 auto BuildEnd = [&] {

2564 *BEF = BEF_end;

2567 EndMemberLookup, CandidateSet,

2568 EndRange, EndExpr);

2571 SemaRef.Diag(EndRange->getBeginLoc(), diag::note_in_for_range)

2572 << ColonLoc << BEF_end << EndRange->getType();

2573 return RangeStatus;

2574 }

2576 diag::err_for_range_iter_deduction_failure)) {

2577 NoteForRangeBeginEndFunction(SemaRef, EndExpr->get(), *BEF);

2579 }

2581 };

2582

2584

2585

2586

2587

2588

2592

2596

2597 if (BeginMemberLookup.empty() != EndMemberLookup.empty()) {

2598

2599

2600

2601

2602 auto BuildNonmember = [&](

2608

2610 return Result;

2611

2612 switch (BuildFound()) {

2615

2619 SemaRef.PDiag(diag::err_for_range_invalid)

2620 << BeginRange->getType() << BEFFound),

2622 [[fallthrough]];

2623

2627 diag::note_for_range_member_begin_end_ignored)

2628 << BeginRange->getType() << BEFFound;

2629 }

2631 }

2632 llvm_unreachable("unexpected ForRangeStatus");

2633 };

2634 if (BeginMemberLookup.empty())

2635 return BuildNonmember(BEF_end, EndMemberLookup, BuildEnd, BuildBegin);

2636 return BuildNonmember(BEF_begin, BeginMemberLookup, BuildBegin, BuildEnd);

2637 }

2638 } else {

2639

2640

2641

2642

2643 }

2644

2646 return Result;

2647 return BuildEnd();

2648}

2649

2650

2651

2652

2656 Stmt *InitStmt,

2657 Stmt *LoopVarDecl,

2659 Expr *Range,

2662

2663

2665 {

2667

2668 AdjustedRange = SemaRef.BuildUnaryOp(S, RangeLoc, UO_Deref, Range);

2671

2673 S, ForLoc, CoawaitLoc, InitStmt, LoopVarDecl, ColonLoc,

2675 if (SR.isInvalid())

2677 }

2678

2679

2680

2681

2682 SemaRef.Diag(RangeLoc, diag::err_for_range_dereference)

2685 S, ForLoc, CoawaitLoc, InitStmt, LoopVarDecl, ColonLoc,

2687}

2688

2695

2696

2697

2698

2699

2700

2701

2702

2703

2705

2709

2712

2716

2718

2720

2721

2722

2724 if (auto *DD = dyn_cast(LoopVar))

2725 for (auto *Binding : DD->bindings()) {

2726 if (!Binding->isParameterPack())

2727 Binding->setType(Context.DependentTy);

2728 }

2730 }

2731 } else if (!BeginDeclStmt.get()) {

2733

2735

2740

2745

2748 if (!Range)

2750 QualType RangeType = Range->getType();

2751

2753 diag::err_for_range_incomplete_type))

2755

2756

2760 for (auto *MTE : LifetimeExtendTemps)

2762 }

2763

2764

2765

2766 const auto DepthStr = std::to_string(S->getDepth() / 2);

2767 VarDecl *BeginVar = BuildForRangeVarDecl(*this, ColonLoc, AutoType,

2768 std::string("__begin") + DepthStr);

2769 VarDecl *EndVar = BuildForRangeVarDecl(*this, ColonLoc, AutoType,

2770 std::string("__end") + DepthStr);

2771

2772

2775

2776

2777

2778

2779

2780

2781 BeginExpr = BeginRangeRef;

2786 }

2788 diag::err_for_range_iter_deduction_failure)) {

2789 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);

2791 }

2792

2793

2795 if (const ConstantArrayType *CAT = dyn_cast(UnqAT))

2797 Context, CAT->getSize(), Context.getPointerDiffType(), RangeLoc);

2799 dyn_cast(UnqAT)) {

2800

2801

2802

2803

2804

2805

2806

2807

2808

2809

2810

2811

2812

2813

2814

2815

2816

2817

2818

2819

2820

2821

2824 true,

2826 VAT->desugar(), RangeLoc))

2827 .getAsOpaquePtr(),

2831

2834 true,

2836 Context.getTrivialTypeSourceInfo(

2837 VAT->getElementType(), RangeLoc))

2838 .getAsOpaquePtr(),

2840 if (SizeOfEachElementExprR.isInvalid())

2842

2843 BoundExpr =

2845 SizeOfVLAExprR.get(), SizeOfEachElementExprR.get());

2848

2849 } else {

2850

2851

2852 llvm_unreachable("Unexpected array type in for-range");

2853 }

2854

2855

2856 EndExpr = ActOnBinOp(S, ColonLoc, tok::plus, EndRangeRef.get(),

2857 BoundExpr.get());

2861 diag::err_for_range_iter_deduction_failure)) {

2862 NoteForRangeBeginEndFunction(*this, EndExpr.get(), BEF_end);

2864 }

2865 } else {

2868 BeginEndFunction BEFFailure;

2870 *this, BeginRangeRef.get(), EndRangeRef.get(), RangeType, BeginVar,

2871 EndVar, ColonLoc, CoawaitLoc, &CandidateSet, &BeginExpr, &EndExpr,

2872 &BEFFailure);

2873

2875 BEFFailure == BEF_begin) {

2876

2877

2878 if (DeclRefExpr *DRE = dyn_cast(Range)) {

2880 QualType ArrayTy = PVD->getOriginalType();

2881 QualType PointerTy = PVD->getType();

2883 Diag(Range->getBeginLoc(), diag::err_range_on_array_parameter)

2884 << RangeLoc << PVD << ArrayTy << PointerTy;

2885 Diag(PVD->getLocation(), diag::note_declared_at);

2887 }

2888 }

2889 }

2890

2891

2892

2894 CoawaitLoc, InitStmt,

2895 LoopVarDecl, ColonLoc,

2896 Range, RangeLoc,

2897 RParenLoc);

2899 return SR;

2900 }

2901

2902

2904 Expr *Range = BEFFailure ? EndRangeRef.get() : BeginRangeRef.get();

2907 PDiag(diag::err_for_range_invalid)

2908 << RangeLoc << Range->getType()

2909 << BEFFailure),

2911 }

2912

2915 }

2916

2918 "invalid range expression in for loop");

2919

2920

2921

2923 if (Context.hasSameType(BeginType, EndType)) {

2925 ? diag::warn_for_range_begin_end_types_differ

2926 : diag::ext_for_range_begin_end_types_differ)

2927 << BeginType << EndType;

2928 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);

2929 NoteForRangeBeginEndFunction(*this, EndExpr.get(), BEF_end);

2930 }

2931

2932 BeginDeclStmt =

2934 EndDeclStmt =

2936

2942

2947

2948

2949 NotEqExpr = ActOnBinOp(S, ColonLoc, tok::exclaimequal,

2950 BeginRef.get(), EndRef.get());

2954 NotEqExpr =

2957 Diag(RangeLoc, diag::note_for_range_invalid_iterator)

2958 << RangeLoc << 0 << BeginRangeRef.get()->getType();

2959 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);

2960 if (Context.hasSameType(BeginType, EndType))

2961 NoteForRangeBeginEndFunction(*this, EndExpr.get(), BEF_end);

2963 }

2964

2965

2970

2971 IncrExpr = ActOnUnaryOp(S, ColonLoc, tok::plusplus, BeginRef.get());

2972 if (!IncrExpr.isInvalid() && CoawaitLoc.isValid())

2973

2974

2975

2977 if (!IncrExpr.isInvalid())

2978 IncrExpr = ActOnFinishFullExpr(IncrExpr.get(), false);

2979 if (IncrExpr.isInvalid()) {

2980 Diag(RangeLoc, diag::note_for_range_invalid_iterator)

2981 << RangeLoc << 2 << BeginRangeRef.get()->getType() ;

2982 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);

2984 }

2985

2986

2991

2994 Diag(RangeLoc, diag::note_for_range_invalid_iterator)

2995 << RangeLoc << 1 << BeginRangeRef.get()->getType();

2996 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);

2998 }

2999

3000

3001

3006 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);

3007 }

3008 }

3009

3010

3011

3014

3015

3016

3019

3021 InitStmt, RangeDS, cast_or_null(BeginDeclStmt.get()),

3022 cast_or_null(EndDeclStmt.get()), NotEqExpr.get(),

3023 IncrExpr.get(), LoopVarDS, nullptr, ForLoc, CoawaitLoc,

3024 ColonLoc, RParenLoc);

3025}

3026

3027

3028

3029

3030

3031

3032

3033

3038 if (!InitExpr)

3039 return;

3040

3042

3043 if (auto Cleanups = dyn_cast(InitExpr))

3044 if (!Cleanups->cleanupsHaveSideEffects())

3045 InitExpr = Cleanups->getSubExpr();

3046

3048 dyn_cast(InitExpr);

3049

3050

3051 if (!MTE)

3052 return;

3053

3055

3056

3057

3059 if (const CXXConstructExpr *CCE = dyn_cast(E)) {

3060 E = CCE->getArg(0);

3064 } else {

3067 }

3069 }

3070

3071 QualType ReferenceReturnType;

3074 } else {

3079 ReferenceReturnType = ReturnType;

3080 }

3081

3082 if (!ReferenceReturnType.isNull()) {

3083

3084

3085

3087 diag::warn_for_range_const_ref_binds_temp_built_from_ref)

3088 << VD << VariableType << ReferenceReturnType;

3093 SemaRef.Diag(VD->getBeginLoc(), diag::note_use_type_or_non_reference)

3094 << NonReferenceType << NewReferenceType << VD->getSourceRange()

3097

3098

3099

3100

3101 SemaRef.Diag(VD->getLocation(), diag::warn_for_range_ref_binds_ret_temp)

3102 << VD << RangeInitType;

3105 SemaRef.Diag(VD->getBeginLoc(), diag::note_use_non_reference_type)

3108 }

3109}

3110

3111

3112

3115 return RD->hasAttr();

3116

3117 return false;

3118}

3119

3120

3121

3122

3126 if (!InitExpr)

3127 return;

3128

3130

3131 if (const CXXConstructExpr *CE = dyn_cast(InitExpr)) {

3132 if (!CE->getConstructor()->isCopyConstructor())

3133 return;

3134 } else if (const CastExpr *CE = dyn_cast(InitExpr)) {

3135 if (CE->getCastKind() != CK_LValueToRValue)

3136 return;

3137 } else {

3138 return;

3139 }

3140

3141

3142

3143

3145 if (Ctx.getTypeSize(VariableType) <= 64 * 8 &&

3148 return;

3149

3150

3151

3152 SemaRef.Diag(VD->getLocation(), diag::warn_for_range_copy)

3153 << VD << VariableType;

3154 SemaRef.Diag(VD->getBeginLoc(), diag::note_use_reference_type)

3158}

3159

3160

3161

3162

3163

3164

3165

3166

3167

3171 return;

3172

3175 diag::warn_for_range_const_ref_binds_temp_built_from_ref, Loc) &&

3176 SemaRef.Diags.isIgnored(diag::warn_for_range_ref_binds_ret_temp, Loc) &&

3177 SemaRef.Diags.isIgnored(diag::warn_for_range_copy, Loc)) {

3178 return;

3179 }

3180

3182 if (!VD)

3183 return;

3184

3186

3188 return;

3189

3191 if (!InitExpr)

3192 return;

3193

3195 return;

3196

3199 ForStmt->getRangeInit()->getType());

3202 }

3203}

3204

3206 if (!S || !B)

3208

3211

3214

3216 diag::warn_empty_range_based_for_body);

3217

3219

3220 return S;

3221}

3222

3227

3228

3229

3230 if (getCurScope()->isInOpenACCComputeConstructScope())

3232

3234 return new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc);

3235}

3236

3240

3249 E = ExprRes.get();

3253 }

3254

3258 E = ExprRes.get();

3259

3261

3262

3263

3264 if (getCurScope()->isInOpenACCComputeConstructScope())

3266

3268}

3269

3271 const Scope &DestScope,

3272 unsigned DeferJumpKind) {

3275 S.Diag(Loc, diag::warn_jump_out_of_seh_finally);

3276 }

3277

3280 assert(Parent);

3281

3282

3283

3284 if (DestScope.Contains(*Parent) || &DestScope == Parent)

3285 S.Diag(Loc, diag::err_jump_out_of_defer_stmt) << DeferJumpKind;

3286 }

3287}

3288

3293 bool IsContinue) {

3294 assert(Target && "not a named break/continue?");

3295

3297

3301 break;

3302

3304 S.Diag(KWLoc, diag::err_acc_branch_in_out_compute_construct)

3305 << 0 << 0;

3306 return nullptr;

3307 }

3308

3312 break;

3313 }

3314 }

3315

3317 if (IsContinue && Found->isContinueScope()) {

3318 S.Diag(LabelLoc, diag::err_continue_switch);

3319 return nullptr;

3320 }

3322 }

3323

3324 S.Diag(LabelLoc, diag::err_break_continue_label_not_found) << IsContinue;

3325 return nullptr;

3326}

3327

3333 LabelLoc,

3334 true);

3335 if (!S)

3337 } else {

3339 }

3340

3341 if (!S) {

3342

3343 return StmtError(Diag(ContinueLoc, diag::err_continue_not_in_loop));

3344 }

3346

3347

3348

3349 return StmtError(Diag(ContinueLoc, diag::err_continue_from_cond_var_init));

3350 }

3351

3352

3353

3354

3357 Diag(ContinueLoc, diag::err_acc_branch_in_out_compute_construct)

3358 << 0 << 0);

3359

3361 diag::DeferJumpKind::Continue);

3362

3364}

3365

3371 LabelLoc,

3372 false);

3373 if (!S)

3375 } else {

3377 }

3378

3379 if (!S) {

3380

3381 return StmtError(Diag(BreakLoc, diag::err_break_not_in_loop_or_switch));

3382 }

3383

3385 return StmtError(Diag(BreakLoc, diag::err_omp_loop_cannot_use_stmt)

3386 << "break");

3387

3388

3389

3390

3391

3392

3393

3394

3399 Diag(BreakLoc, diag::err_acc_branch_in_out_compute_construct)

3400 << 0 << 0);

3401

3403 diag::DeferJumpKind::Break);

3404

3406}

3407

3410 if (!E)

3412

3413

3414 const auto *DR = dyn_cast(E->IgnoreParens());

3415 if (!DR || DR->refersToEnclosingVariableOrCapture())

3417 const auto *VD = dyn_cast(DR->getDecl());

3418 if (!VD)

3430 }

3431 return Res;

3432}

3433

3436

3437

3438

3439

3440 if (VD->getKind() == Decl::ParmVar)

3442 else if (VD->getKind() != Decl::Var)

3444

3445

3448

3449

3452

3453

3454

3455 if (VD->hasAttr())

3457

3460

3461

3465

3466

3467

3473 } else {

3475 }

3476

3477

3478

3480 Context.getDeclAlign(VD) > Context.getTypeAlignInChars(VDType))

3482

3483 return Info;

3484}

3485

3489 return nullptr;

3490

3491 auto invalidNRVO = [&] {

3493 return nullptr;

3494 };

3495

3496

3497

3498

3499

3500 if ((ReturnType->getTypeClass() == Type::TypeClass::Auto &&

3503 return invalidNRVO();

3504

3506

3507

3509 return invalidNRVO();

3510

3512

3513

3515 Context.hasSameUnqualifiedType(ReturnType, VDType))

3517 }

3519}

3520

3521

3522

3523

3524

3525

3526static bool

3529 const auto *Step = llvm::find_if(Seq.steps(), [](const auto &Step) {

3530 return Step.Kind == InitializationSequence::SK_ConstructorInitialization ||

3531 Step.Kind == InitializationSequence::SK_UserConversion;

3532 });

3533 if (Step != Seq.step_end()) {

3534 const auto *FD = Step->Function.Function;

3538 return false;

3539 }

3540 return true;

3541}

3542

3545 bool SupressSimplerImplicitMoves) {

3551 Expr *InitExpr = &AsRvalue;

3553 Value->getBeginLoc());

3555 auto Res = Seq.getFailedOverloadResult();

3559

3560

3564

3565

3566 return Seq.Perform(*this, Entity, Kind, Value);

3567 }

3568 }

3569

3570

3571

3573}

3574

3575

3576

3582

3584 Expr *RetValExp,

3586 bool SupressSimplerImplicitMoves) {

3587

3588

3591 LambdaScopeInfo *CurLambda = dyn_cast(CurCap);

3594 bool HasDeducedReturnType =

3596

3597 if (ExprEvalContexts.back().isDiscardedStatementContext() &&

3599 if (RetValExp) {

3604 RetValExp = ER.get();

3605 }

3607 nullptr);

3608 }

3609

3610 if (HasDeducedReturnType) {

3612

3613

3614

3617

3618

3621

3623 assert(AT && "lost auto type from lambda return type");

3626

3628 }

3631

3632

3633

3634

3637 if (Result.isInvalid())

3639 RetValExp = Result.get();

3640

3641

3642

3643

3644

3645 if (CurContext->isDependentContext())

3647 else

3649 } else {

3650 if (RetValExp) {

3651

3652

3653

3654 Diag(ReturnLoc, diag::err_lambda_return_init_list)

3656 }

3657

3658 FnRetType = Context.VoidTy;

3659 }

3660

3661

3662

3665 }

3667

3668 if (auto *CurBlock = dyn_cast(CurCap)) {

3670 Diag(ReturnLoc, diag::err_noreturn_has_return_expr)

3671 << diag::FalloffFunctionKind::Block;

3673 }

3674 } else if (auto *CurRegion = dyn_cast(CurCap)) {

3675 Diag(ReturnLoc, diag::err_return_in_captured_stmt) << CurRegion->getRegionName();

3677 } else {

3678 assert(CurLambda && "unknown kind of captured scope");

3682 Diag(ReturnLoc, diag::err_noreturn_has_return_expr)

3683 << diag::FalloffFunctionKind::Lambda;

3685 }

3686 }

3687

3688

3689

3690

3692

3693

3694 } else if (FnRetType->isVoidType()) {

3701 Diag(ReturnLoc, diag::ext_return_has_void_expr) << "literal" << 2;

3702 else {

3703 Diag(ReturnLoc, diag::err_return_block_has_expr);

3704 RetValExp = nullptr;

3705 }

3706 }

3707 } else if (!RetValExp) {

3708 return StmtError(Diag(ReturnLoc, diag::err_block_return_missing_expr));

3710

3711

3712

3713

3714

3715

3716

3717

3721 Entity, NRInfo, RetValExp, SupressSimplerImplicitMoves);

3723

3725 }

3726 RetValExp = Res.get();

3727 CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc);

3728 }

3729

3730 if (RetValExp) {

3735 RetValExp = ER.get();

3736 }

3739

3740

3741

3742

3745

3746 if (FunctionScopes.back()->FirstReturnLoc.isInvalid())

3748

3749 if (auto *CurBlock = dyn_cast(CurCap);

3752 CurBlock->TheDecl->setInvalidDecl();

3753

3755}

3756

3757namespace {

3758

3759

3760

3761

3762

3763

3764

3765

3766

3767

3768

3769

3771public:

3772 LocalTypedefNameReferencer(Sema &S) : S(S) {}

3773 bool VisitRecordType(RecordType *RT) override;

3774

3775private:

3777};

3778bool LocalTypedefNameReferencer::VisitRecordType(RecordType *RT) {

3779 auto *R = dyn_cast(RT->getDecl());

3780 if (!R || !R->isLocalClass() || !R->isLocalClass()->isExternallyVisible() ||

3781 R->isDependentType())

3782 return true;

3783 for (auto *TmpD : R->decls())

3784 if (auto *T = dyn_cast(TmpD))

3785 if (T->getAccess() != AS_private || R->hasFriends())

3787 return true;

3788}

3789}

3790

3795 .getReturnLoc();

3796}

3797

3800 Expr *RetExpr, const AutoType *AT) {

3801

3802

3803

3805 return false;

3806

3807 if (isa_and_nonnull(RetExpr)) {

3808

3809

3811 getCurLambda() ? diag::err_lambda_return_init_list

3812 : diag::err_auto_fn_return_init_list)

3814 return true;

3815 }

3816

3818

3819

3820

3821

3822 assert(AT->isDeduced() && "should have deduced to dependent type");

3823 return false;

3824 }

3825

3827

3828

3830 if (!RetExpr) {

3831

3832

3833

3834

3835 if (!OrigResultType.getType()->getAs()) {

3836 Diag(ReturnLoc, diag::err_auto_fn_return_void_but_not_auto)

3837 << OrigResultType.getType();

3838 return true;

3839 }

3840 RetExpr = &VoidVal;

3841 }

3842

3843 QualType Deduced = AT->getDeducedType();

3844 {

3845

3846

3847 auto RetExprLoc = RetExpr->getExprLoc();

3852 if (FindResult.Expression)

3853 TemplateSpecLoc = FindResult.Expression->getNameLoc();

3854 }

3857 OrigResultType, RetExpr, Deduced, Info, false,

3858 false, &FailedTSC);

3860 return true;

3861 switch (Res) {

3863 break;

3865 return true;

3867

3868

3869

3870

3873 Diag(ReturnLoc, diag::err_typecheck_missing_return_type_incompatible)

3875 else

3876 Diag(ReturnLoc, diag::err_auto_fn_different_deductions)

3877 << (AT->isDecltypeAuto() ? 1 : 0) << Info.SecondArg

3879 return true;

3880 }

3881 default:

3882 Diag(RetExpr->getExprLoc(), diag::err_auto_fn_deduction_failure)

3885 return true;

3886 }

3887 }

3888

3889

3890

3891 LocalTypedefNameReferencer(*this).TraverseType(RetExpr->getType());

3892

3893

3896 Diag(FD->getLocation(), diag::err_kern_type_not_void_return)

3898 return true;

3899 }

3900

3901 if (!FD->isInvalidDecl() && AT->getDeducedType() != Deduced)

3902

3903 Context.adjustDeducedFunctionResultType(FD, Deduced);

3904

3908 diag::warn_qual_return_type,

3910 return false;

3911}

3912

3915 Scope *CurScope) {

3919

3920 if (getCurScope()->isInOpenACCComputeConstructScope())

3922 Diag(ReturnLoc, diag::err_acc_branch_in_out_compute_construct)

3923 << 1 << 0);

3924

3925

3929 "first coroutine location not set");

3930 Diag(ReturnLoc, diag::err_return_in_coroutine);

3933 }

3934

3935 CheckInvalidBuiltinCountedByRef(RetVal.get(),

3937

3941 return R;

3942

3945

3946 CurScope->updateNRVOCandidate(VD);

3947

3949 diag::DeferJumpKind::Return);

3950

3951 return R;

3952}

3953

3957

3962

3964 [[maybe_unused]] Scope *CurScope) {

3970}

3971

3973 const Expr *E) {

3975 return false;

3978 return false;

3981 return true;

3982 }

3983 return false;

3984}

3985

3987 bool AllowRecovery) {

3988

3991

3992

3993

3994

3995 bool SupressSimplerImplicitMoves =

4000

4003 SupressSimplerImplicitMoves);

4004

4007 const AttrVec *Attrs = nullptr;

4008 bool isObjCMethod = false;

4009

4015 Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr) << FD;

4016 if (FD->isMain() && RetValExp)

4018 Diag(ReturnLoc, diag::warn_main_returns_bool_literal)

4020 if (FD->hasAttr() && RetValExp) {

4021 if (const auto *RT = dyn_cast(FnRetType.getCanonicalType())) {

4022 if (RT->getDecl()->isOrContainsUnion())

4023 Diag(RetValExp->getBeginLoc(), diag::warn_cmse_nonsecure_union) << 1;

4024 }

4025 }

4027 FnRetType = MD->getReturnType();

4028 isObjCMethod = true;

4029 if (MD->hasAttrs())

4030 Attrs = &MD->getAttrs();

4031 if (MD->hasRelatedResultType() && MD->getClassInterface()) {

4032

4033

4034

4035 RelatedRetType = Context.getObjCInterfaceType(MD->getClassInterface());

4036 RelatedRetType = Context.getObjCObjectPointerType(RelatedRetType);

4037 }

4038 } else

4040

4041 if (RetValExp) {

4042 const auto *ATy = dyn_cast(RetValExp->getType());

4043 if (ATy && ATy->getElementType().isWebAssemblyReferenceType()) {

4044 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;

4046 }

4047 }

4048

4049

4050

4051 if (ExprEvalContexts.back().isDiscardedStatementContext() &&

4053 if (RetValExp) {

4058 RetValExp = ER.get();

4059 }

4061 nullptr);

4062 }

4063

4064

4065

4069

4070

4071

4072

4076 if (!AllowRecovery)

4078

4079 if (RetValExp) {

4080

4081

4084 AT->isDeduced() ? FnRetType : QualType());

4085 if (Recovery.isInvalid())

4087 RetValExp = Recovery.get();

4088 } else {

4089

4090 }

4091 } else {

4093 }

4094 }

4095 }

4097

4098 bool HasDependentReturnType = FnRetType->isDependentType();

4099

4102 if (RetValExp) {

4103 if (auto *ILE = dyn_cast(RetValExp)) {

4104

4105

4106

4108 int FunctionKind = 0;

4110 FunctionKind = 1;

4112 FunctionKind = 2;

4114 FunctionKind = 3;

4115

4116 Diag(ReturnLoc, diag::err_return_init_list)

4117 << CurDecl << FunctionKind << RetValExp->getSourceRange();

4118

4119

4120 RetValExp = AllowRecovery

4122 ILE->getRBraceLoc(), ILE->inits())

4124 : nullptr;

4126

4127 unsigned D = diag::ext_return_has_expr;

4132 D = diag::err_ctor_dtor_returns_void;

4133 else

4134 D = diag::ext_return_has_void_expr;

4135 }

4136 else {

4139 if (Result.isInvalid())

4141 RetValExp = Result.get();

4144 }

4145

4146 if (D == diag::err_ctor_dtor_returns_void) {

4148 Diag(ReturnLoc, D) << CurDecl << isa(CurDecl)

4150 }

4151

4152 else if (D != diag::ext_return_has_void_expr ||

4155

4156 int FunctionKind = 0;

4158 FunctionKind = 1;

4160 FunctionKind = 2;

4162 FunctionKind = 3;

4163

4164 Diag(ReturnLoc, D)

4165 << CurDecl << FunctionKind << RetValExp->getSourceRange();

4166 }

4167 }

4168

4169 if (RetValExp) {

4174 RetValExp = ER.get();

4175 }

4176 }

4177

4179 nullptr);

4180 } else if (!RetValExp && !HasDependentReturnType) {

4182

4184

4186

4187 Diag(ReturnLoc, diag::err_constexpr_return_missing_expr)

4190 } else {

4191

4192

4193 unsigned DiagID = getLangOpts().C99 ? diag::ext_return_missing_expr

4194 : diag::warn_return_missing_expr;

4195

4196

4198 "Not in a FunctionDecl or ObjCMethodDecl?");

4199 bool IsMethod = FD == nullptr;

4202 Diag(ReturnLoc, DiagID) << ND << IsMethod;

4203 }

4204

4206 nullptr);

4207 } else {

4208 assert(RetValExp || HasDependentReturnType);

4209 QualType RetType = RelatedRetType.isNull() ? FnRetType : RelatedRetType;

4210

4211

4212

4213

4214

4215

4216

4217 if (!HasDependentReturnType && !RetValExp->isTypeDependent()) {

4218

4222 Entity, NRInfo, RetValExp, SupressSimplerImplicitMoves);

4223 if (Res.isInvalid() && AllowRecovery)

4225 RetValExp->getEndLoc(), RetValExp, RetType);

4227

4229 }

4231

4232

4233

4234

4235

4236 if (!RelatedRetType.isNull()) {

4238 FnRetType);

4241

4243 }

4245 }

4246

4247 CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc, isObjCMethod, Attrs,

4249 }

4250

4251 if (RetValExp) {

4256 RetValExp = ER.get();

4257 }

4259 }

4260

4261

4262

4263 if (Result->getNRVOCandidate())

4265

4266 if (FunctionScopes.back()->FirstReturnLoc.isInvalid())

4268

4270}

4271

4274 Stmt *HandlerBlock) {

4275

4277 CXXCatchStmt(CatchLoc, cast_or_null(ExDecl), HandlerBlock);

4278}

4279

4280namespace {

4281class CatchHandlerType {

4283 LLVM_PREFERRED_TYPE(bool)

4284 unsigned IsPointer : 1;

4285

4286

4287

4288 friend struct llvm::DenseMapInfo;

4289 enum Unique { ForDenseMap };

4290 CatchHandlerType(QualType QT, Unique) : QT(QT), IsPointer(false) {}

4291

4292public:

4293

4294

4295

4296 CatchHandlerType(QualType Q) : QT(Q), IsPointer(false) {

4298 IsPointer = true;

4299

4303 }

4304

4305

4306

4307

4308 CatchHandlerType(QualType QT, bool IsPointer)

4309 : QT(QT), IsPointer(IsPointer) {}

4310

4311 QualType underlying() const { return QT; }

4312 bool isPointer() const { return IsPointer; }

4313

4314 friend bool operator==(const CatchHandlerType &LHS,

4315 const CatchHandlerType &RHS) {

4316

4317 if (LHS.IsPointer != RHS.IsPointer)

4318 return false;

4319

4320 return LHS.QT == RHS.QT;

4321 }

4322};

4323}

4324

4325namespace llvm {

4326template <> struct DenseMapInfo {

4328 return CatchHandlerType(DenseMapInfo::getEmptyKey(),

4329 CatchHandlerType::ForDenseMap);

4330 }

4331

4333 return CatchHandlerType(DenseMapInfo::getTombstoneKey(),

4334 CatchHandlerType::ForDenseMap);

4335 }

4336

4338 return DenseMapInfo::getHashValue(Base.underlying());

4339 }

4340

4341 static bool isEqual(const CatchHandlerType &LHS,

4342 const CatchHandlerType &RHS) {

4343 return LHS == RHS;

4344 }

4345};

4346}

4347

4348namespace {

4349class CatchTypePublicBases {

4350 const llvm::DenseMap<QualType, CXXCatchStmt *> &TypesToCheck;

4351

4352 CXXCatchStmt *FoundHandler;

4353 QualType FoundHandlerType;

4354 QualType TestAgainstType;

4355

4356public:

4357 CatchTypePublicBases(const llvm::DenseMap<QualType, CXXCatchStmt *> &T,

4358 QualType QT)

4359 : TypesToCheck(T), FoundHandler(nullptr), TestAgainstType(QT) {}

4360

4361 CXXCatchStmt *getFoundHandler() const { return FoundHandler; }

4362 QualType getFoundHandlerType() const { return FoundHandlerType; }

4363

4364 bool operator()(const CXXBaseSpecifier *S, CXXBasePath &) {

4367 const auto &M = TypesToCheck;

4368 auto I = M.find(Check);

4369 if (I != M.end()) {

4370

4371

4372

4373

4374

4375

4376

4377

4378

4379

4380 if (I->second->getCaughtType()->isPointerType() ==

4382 FoundHandler = I->second;

4383 FoundHandlerType = Check;

4384 return true;

4385 }

4386 }

4387 }

4388 return false;

4389 }

4390};

4391}

4392

4395 const llvm::Triple &T = Context.getTargetInfo().getTriple();

4396 const bool IsOpenMPGPUTarget =

4397 getLangOpts().OpenMPIsTargetDevice && T.isGPU();

4398

4400

4401

4402

4403 if (IsOpenMPGPUTarget)

4404 targetDiag(TryLoc, diag::warn_try_not_valid_on_target) << T.str();

4405

4406

4410

4412 Diag(TryLoc, diag::err_omp_simd_region_cannot_use_stmt) << "try";

4413

4415

4416

4418 Diag(TryLoc, diag::err_mixing_cxx_try_seh_try) << 0;

4419 Diag(FSI->FirstSEHTryLoc, diag::note_conflicting_try_here) << "'__try'";

4420 }

4421

4422 const unsigned NumHandlers = Handlers.size();

4423 assert(!Handlers.empty() &&

4424 "The parser shouldn't call this if there are no handlers.");

4425

4426 llvm::DenseMap<QualType, CXXCatchStmt *> HandledBaseTypes;

4427 llvm::DenseMap<CatchHandlerType, CXXCatchStmt *> HandledTypes;

4428 for (unsigned i = 0; i < NumHandlers; ++i) {

4430

4431

4432

4433

4435 if (i < NumHandlers - 1)

4437 continue;

4439 continue;

4440

4441

4442

4443

4445

4446

4447

4448

4449 QualType Underlying = HandlerCHT.underlying();

4451 if (!RD->hasDefinition())

4452 continue;

4453

4454

4455

4456

4457

4460 CatchTypePublicBases CTPB(HandledBaseTypes,

4462 if (RD->lookupInBases(CTPB, Paths)) {

4463 const CXXCatchStmt *Problem = CTPB.getFoundHandler();

4467 diag::warn_exception_caught_by_earlier_handler)

4470 diag::note_previous_exception_handler)

4472 }

4473 }

4474

4475

4476

4478 }

4479

4480

4481

4482 auto R = HandledTypes.insert(

4484 if (!R.second) {

4485 const CXXCatchStmt *Problem = R.first->second;

4487 diag::warn_exception_caught_by_earlier_handler)

4490 diag::note_previous_exception_handler)

4492 }

4493 }

4494

4496

4498 Handlers);

4499}

4500

4502 const llvm::Triple &T = Context.getTargetInfo().getTriple();

4503 const bool IsOpenMPGPUTarget =

4504 getLangOpts().OpenMPIsTargetDevice && T.isGPU();

4505

4506

4507

4509

4510 return;

4511

4515 targetDiag(Loc, diag::err_exceptions_disabled) << (IsTry ? "try" : "throw");

4516}

4517

4519 Stmt *TryBlock, Stmt *Handler) {

4520 assert(TryBlock && Handler);

4521

4523

4524

4525

4528 Diag(TryLoc, diag::err_mixing_cxx_try_seh_try) << FSI->FirstTryType;

4531 ? "'try'"

4532 : "'@try'");

4533 }

4534 }

4535

4537

4538

4539

4543 FunctionDecl *FD = dyn_cast_or_null(DC);

4544 if (FD)

4546 else

4547 Diag(TryLoc, diag::err_seh_try_outside_functions);

4548

4549

4550 if (Context.getTargetInfo().isSEHTrySupported())

4551 Diag(TryLoc, diag::err_seh_try_unsupported);

4552

4554}

4555

4558 assert(FilterExpr && Block);

4562 Diag(FilterExpr->getExprLoc(), diag::err_filter_expression_integral)

4563 << FTy);

4564 }

4566}

4567

4571

4575

4581

4584 Scope *SEHTryParent = CurScope;

4585 while (SEHTryParent && !SEHTryParent->isSEHTryScope())

4586 SEHTryParent = SEHTryParent->getParent();

4587 if (!SEHTryParent)

4588 return StmtError(Diag(Loc, diag::err_ms___leave_not_in___try));

4590 diag::DeferJumpKind::SEHLeave);

4591

4593}

4594

4596 bool IsIfExists,

4599 Stmt *Nested)

4600{

4602 QualifierLoc, NameInfo,

4604}

4605

4606

4608 bool IsIfExists,

4611 Stmt *Nested) {

4615 Nested);

4616}

4617

4620 unsigned NumParams) {

4624

4628 nullptr);

4629 else

4631 nullptr);

4632

4637

4638 assert(NumParams > 0 && "CapturedStmt requires context parameter");

4641 return RD;

4642}

4643

4644static bool

4650 continue;

4651

4652

4655

4656

4657

4658

4659

4661

4662

4667 Captures.push_back(

4669 } else {

4671

4675

4681 }

4682 CaptureInits.push_back(Init.get());

4683 }

4684 return false;

4685}

4686

4687static std::optional

4690 return {};

4693 return 0;

4695 return 1;

4697 return 2;

4698 }

4699 return {};

4700}

4701

4704 unsigned NumParams) {

4706 Diag(Loc, diag::err_sme_openmp_captured_region) << *ErrorIndex;

4707

4710

4711

4715 Context.getPointerType(Context.getCanonicalTagType(RD));

4716 auto *Param =

4720

4722

4723

4725

4726 if (CurScope)

4728 else

4730

4733 ExprEvalContexts.back().InImmediateEscalatingFunctionContext = false;

4734}

4735

4739 unsigned OpenMPCaptureLevel) {

4741 Diag(Loc, diag::err_sme_openmp_captured_region) << *ErrorIndex;

4742

4745

4746

4748 bool ContextIsFound = false;

4749 unsigned ParamNum = 0;

4751 E = Params.end();

4752 I != E; ++I, ++ParamNum) {

4753 if (I->second.isNull()) {

4754 assert(!ContextIsFound &&

4755 "null type has been found already for '__context' parameter");

4758 Context.getPointerType(Context.getCanonicalTagType(RD))

4759 .withConst()

4760 .withRestrict();

4761 auto *Param =

4766 ContextIsFound = true;

4767 } else {

4769 auto *Param =

4773 CD->setParam(ParamNum, Param);

4774 }

4775 }

4776 assert(ContextIsFound && "no null type for '__context' parameter");

4777 if (!ContextIsFound) {

4778

4781 Context.getPointerType(Context.getCanonicalTagType(RD));

4782 auto *Param =

4787 }

4788

4790

4791 if (CurScope)

4793 else

4795

4798}

4799

4806

4808 Record->setInvalidDecl();

4809

4813}

4814

4816

4817

4823

4828

4831

4834 Captures, CaptureInits, CD, RD);

4835

4838

4839 return Res;

4840}

Defines the clang::ASTContext interface.

This file provides some common utility functions for processing Lambda related AST Constructs.

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

llvm::MachO::Target Target

llvm::MachO::Record Record

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.

This file declares semantic analysis for CUDA constructs.

This file declares semantic analysis for Objective-C.

This file declares semantic analysis for OpenMP constructs and clauses.

static bool CmpEnumVals(const std::pair< llvm::APSInt, EnumConstantDecl * > &lhs, const std::pair< llvm::APSInt, EnumConstantDecl * > &rhs)

CmpEnumVals - Comparison predicate for sorting enumeration values.

Definition SemaStmt.cpp:1082

static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init, SourceLocation Loc, int DiagID)

Finish building a variable declaration for a for-range statement.

Definition SemaStmt.cpp:2333

static bool CmpCaseVals(const std::pair< llvm::APSInt, CaseStmt * > &lhs, const std::pair< llvm::APSInt, CaseStmt * > &rhs)

CmpCaseVals - Comparison predicate for sorting case values.

Definition SemaStmt.cpp:1069

SmallVector< std::pair< llvm::APSInt, EnumConstantDecl * >, 64 > EnumValsTy

Definition SemaStmt.cpp:1233

static bool ShouldDiagnoseSwitchCaseNotInEnum(const Sema &S, const EnumDecl *ED, const Expr *CaseExpr, EnumValsTy::iterator &EI, EnumValsTy::iterator &EIEnd, const llvm::APSInt &Val)

Returns true if we should emit a diagnostic about this case expression not being a part of the enum u...

Definition SemaStmt.cpp:1237

static bool DiagnoseUnusedComparison(Sema &S, const Expr *E)

Diagnose unused comparisons, both builtin and overloaded operators.

Definition SemaStmt.cpp:131

static Scope * FindLabeledBreakContinueScope(Sema &S, Scope *CurScope, SourceLocation KWLoc, LabelDecl *Target, SourceLocation LabelLoc, bool IsContinue)

Definition SemaStmt.cpp:3289

static bool EqEnumVals(const std::pair< llvm::APSInt, EnumConstantDecl * > &lhs, const std::pair< llvm::APSInt, EnumConstantDecl * > &rhs)

EqEnumVals - Comparison preficate for uniqing enumeration values.

Definition SemaStmt.cpp:1090

static std::optional< int > isOpenMPCapturedRegionInArmSMEFunction(Sema const &S, CapturedRegionKind Kind)

Definition SemaStmt.cpp:4688

static bool hasDeducedReturnType(FunctionDecl *FD)

Determine whether the declared return type of the specified function contains 'auto'.

Definition SemaStmt.cpp:3577

static bool ObjCEnumerationCollection(Expr *Collection)

Definition SemaStmt.cpp:2426

static void DiagnoseForRangeConstVariableCopies(Sema &SemaRef, const VarDecl *VD)

Definition SemaStmt.cpp:3123

static StmtResult RebuildForRangeWithDereference(Sema &SemaRef, Scope *S, SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *InitStmt, Stmt *LoopVarDecl, SourceLocation ColonLoc, Expr *Range, SourceLocation RangeLoc, SourceLocation RParenLoc)

Speculatively attempt to dereference an invalid range expression.

Definition SemaStmt.cpp:2653

static void checkEnumTypesInSwitchStmt(Sema &S, const Expr *Cond, const Expr *Case)

Definition SemaStmt.cpp:1269

static void DiagnoseForRangeReferenceVariableCopies(Sema &SemaRef, const VarDecl *VD, QualType RangeInitType)

Definition SemaStmt.cpp:3034

static void DiagnoseForRangeVariableCopies(Sema &SemaRef, const CXXForRangeStmt *ForStmt)

DiagnoseForRangeVariableCopies - Diagnose three cases and fixes for them.

Definition SemaStmt.cpp:3168

static bool CheckSimplerImplicitMovesMSVCWorkaround(const Sema &S, const Expr *E)

Definition SemaStmt.cpp:3972

static bool VerifyInitializationSequenceCXX98(const Sema &S, const InitializationSequence &Seq)

Verify that the initialization sequence that was picked for the first overload resolution is permissi...

Definition SemaStmt.cpp:3527

static QualType GetTypeBeforeIntegralPromotion(const Expr *&E)

GetTypeBeforeIntegralPromotion - Returns the pre-promotion type of potentially integral-promoted expr...

Definition SemaStmt.cpp:1098

static Sema::ForRangeStatus BuildNonArrayForRange(Sema &SemaRef, Expr *BeginRange, Expr *EndRange, QualType RangeType, VarDecl *BeginVar, VarDecl *EndVar, SourceLocation ColonLoc, SourceLocation CoawaitLoc, OverloadCandidateSet *CandidateSet, ExprResult *BeginExpr, ExprResult *EndExpr, BeginEndFunction *BEF)

Create the initialization, compare, and increment steps for the range-based for loop expression.

Definition SemaStmt.cpp:2519

static bool hasTrivialABIAttr(QualType VariableType)

Determines whether the VariableType's declaration is a record with the clang::trivial_abi attribute.

Definition SemaStmt.cpp:3113

static void CheckJumpOutOfSEHFinallyOrDefer(Sema &S, SourceLocation Loc, const Scope &DestScope, unsigned DeferJumpKind)

Definition SemaStmt.cpp:3270

static void AdjustAPSInt(llvm::APSInt &Val, unsigned BitWidth, bool IsSigned)

Definition SemaStmt.cpp:1204

static bool buildCapturedStmtCaptureList(Sema &S, CapturedRegionScopeInfo *RSI, SmallVectorImpl< CapturedStmt::Capture > &Captures, SmallVectorImpl< Expr * > &CaptureInits)

Definition SemaStmt.cpp:4645

static bool DiagnoseNoDiscard(Sema &S, const NamedDecl *OffendingDecl, const WarnUnusedResultAttr *A, SourceLocation Loc, SourceRange R1, SourceRange R2, bool IsCtor)

Definition SemaStmt.cpp:202

static void checkCaseValue(Sema &S, SourceLocation Loc, const llvm::APSInt &Val, unsigned UnpromotedWidth, bool UnpromotedSign)

Check the specified case value is in range for the given unpromoted switch type.

Definition SemaStmt.cpp:1211

Defines the Objective-C statement AST node classes.

Defines the clang::TypeLoc interface and its subclasses.

Allows QualTypes to be sorted and hence used in maps and sets.

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

QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const

Return the uniqued reference to the type for an lvalue reference to the specified type.

TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const

Allocate a TypeSourceInfo where all locations have been initialized to a given location,...

uint64_t getTypeSize(QualType T) const

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

CanQualType getCanonicalTagType(const TagDecl *TD) const

static bool hasSameUnqualifiedType(QualType T1, QualType T2)

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

Represents an array type, per C99 6.7.5.2 - Array Declarators.

Attr - This represents one attribute.

SourceLocation getLocation() const

SourceRange getRange() const

static AttributedStmt * Create(const ASTContext &C, SourceLocation Loc, ArrayRef< const Attr * > Attrs, Stmt *SubStmt)

Expr * getFalseExpr() const

getFalseExpr - Return the subexpression which will be evaluated if the condition evaluates to false; ...

OpaqueValueExpr * getOpaqueValue() const

getOpaqueValue - Return the opaque value placeholder.

A builtin binary operation expression such as "x + y" or "x <= y".

SourceLocation getExprLoc() const

BreakStmt - This represents a break.

CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....

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

void setOrigin(const CXXRecordDecl *Rec)

bool isAmbiguous(CanQualType BaseType) const

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

QualType getType() const

Retrieves the type of the base class.

AccessSpecifier getAccessSpecifier() const

Returns the access specifier for this base specifier.

Represents binding an expression to a temporary.

CXXCatchStmt - This represents a C++ catch block.

SourceLocation getBeginLoc() const LLVM_READONLY

VarDecl * getExceptionDecl() const

QualType getCaughtType() const

Represents a call to a C++ constructor.

Represents a C++ conversion function within a class.

CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...

DeclStmt * getBeginStmt()

DeclStmt * getRangeStmt()

Represents an explicit C++ type conversion that uses "functional" notation (C++ [expr....

Represents a call to a member function that may be written either with member call syntax (e....

A call to an overloaded operator written using operator syntax.

Represents a C++ struct/union/class.

static CXXRecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl=nullptr)

An expression "T()" which creates an rvalue of a non-class type T.

Represents a C++ nested-name-specifier or a global scope specifier.

NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const

Retrieve a nested-name-specifier with location information, copied into the given AST context.

static CXXTryStmt * Create(const ASTContext &C, SourceLocation tryLoc, CompoundStmt *tryBlock, ArrayRef< Stmt * > handlers)

CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).

static CanQual< Type > CreateUnsafe(QualType Other)

Represents the body of a CapturedStmt, and serves as its DeclContext.

static DeclContext * castToDeclContext(const CapturedDecl *D)

void setContextParam(unsigned i, ImplicitParamDecl *P)

void setParam(unsigned i, ImplicitParamDecl *P)

static CapturedDecl * Create(ASTContext &C, DeclContext *DC, unsigned NumParams)

Describes the capture of either a variable, or 'this', or variable-length array type.

This captures a statement into a function.

Stmt * getCapturedStmt()

Retrieve the statement being captured.

static CapturedStmt * Create(const ASTContext &Context, Stmt *S, CapturedRegionKind Kind, ArrayRef< Capture > Captures, ArrayRef< Expr * > CaptureInits, CapturedDecl *CD, RecordDecl *RD)

CaseStmt - Represent a case statement.

static CaseStmt * Create(const ASTContext &Ctx, Expr *lhs, Expr *rhs, SourceLocation caseLoc, SourceLocation ellipsisLoc, SourceLocation colonLoc)

Build a case statement.

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

CastKind getCastKind() const

CompoundStmt - This represents a group of statements like { stmt stmt }.

static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)

Expr * getFalseExpr() const

getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...

Expr * getCond() const

getCond - Return the expression representing the condition for the ?

Expr * getTrueExpr() const

getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...

ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.

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

ContinueStmt - This represents a continue.

DeclContext - This is used only as base class of specific decl types that can act as declaration cont...

DeclContext * getParent()

getParent - Returns the containing DeclContext.

bool isFileContext() const

bool isDependentContext() const

Determines whether this context is dependent on a template parameter.

void addDecl(Decl *D)

Add the declaration D into this context.

bool isStdNamespace() const

bool isFunctionOrMethod() const

void addHiddenDecl(Decl *D)

Add the declaration D to this context without modifying any lookup tables.

bool isSingleDecl() const

A reference to a declared variable, function, enum, etc.

SourceLocation getLocation() const

DeclStmt - Adaptor class for mixing declarations with statements and expressions.

bool isSingleDecl() const

isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.

const Decl * getSingleDecl() const

SourceLocation getBeginLoc() const LLVM_READONLY

Decl - This represents one declaration (or definition), e.g.

void setInvalidDecl(bool Invalid=true)

setInvalidDecl - Indicates the Decl had a semantic error.

void markUsed(ASTContext &C)

Mark the declaration used, in the sense of odr-use.

static Decl * castFromDeclContext(const DeclContext *)

bool isInvalidDecl() const

SourceLocation getLocation() const

void setImplicit(bool I=true)

void setLocation(SourceLocation L)

DeclContext * getDeclContext()

SourceLocation getTypeSpecEndLoc() const

SourceLocation getTypeSpecStartLoc() const

SourceLocation getBeginLoc() const LLVM_READONLY

TypeSourceInfo * getTypeSourceInfo() const

SourceLocation getDefaultLoc() const

static DeferStmt * Create(ASTContext &Context, SourceLocation DeferLoc, Stmt *Body)

bool isIgnored(unsigned DiagID, SourceLocation Loc) const

Determine whether the diagnostic is known to be ignored.

DoStmt - This represents a 'do/while' stmt.

bool isClosed() const

Returns true if this enum is either annotated with enum_extensibility(closed) or isn't annotated with...

EvaluatedExprVisitor - This class visits 'Expr *'s.

This represents one expression.

bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const

EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...

@ SE_AllowSideEffects

Allow any unmodeled side effect.

Expr * IgnoreParenCasts() LLVM_READONLY

Skip past any parentheses and casts which might surround this expression until reaching a fixed point...

bool isUnusedResultAWarning(const Expr *&WarnExpr, SourceLocation &Loc, SourceRange &R1, SourceRange &R2, ASTContext &Ctx) const

isUnusedResultAWarning - Return true if this immediate expression should be warned about if the resul...

bool isValueDependent() const

Determines whether the value of this expression depends on.

bool isTypeDependent() const

Determines whether the type of this expression depends on.

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

EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.

Expr * IgnoreParenImpCasts() LLVM_READONLY

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

bool containsErrors() const

Whether this expression contains subexpressions which had errors.

Expr * IgnoreParens() LLVM_READONLY

Skip past any parentheses which might surround this expression until reaching a fixed point.

std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const

isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.

Decl * getReferencedDeclOfCallee()

bool isInstantiationDependent() const

Whether this expression is instantiation-dependent, meaning that it depends in some way on.

Expr * IgnoreImpCasts() LLVM_READONLY

Skip past any implicit casts which might surround this expression until reaching a fixed point.

SourceLocation getExprLoc() const LLVM_READONLY

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

bool isKnownToHaveBooleanValue(bool Semantic=true) const

isKnownToHaveBooleanValue - Return true if this is an integer expression that is known to return 0 or...

Represents difference between two FPOptions values.

FPOptionsOverride getChangesFrom(const FPOptions &Base) const

Return difference with the given option set.

Represents a member of a struct/union/class.

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 CreateRemoval(CharSourceRange RemoveRange)

Create a code modification hint that removes the given source range.

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.

ForStmt - This represents a 'for (init;cond;inc)' stmt.

SourceLocation getRParenLoc() const

SourceLocation getBeginLoc() const

FullExpr - Represents a "full-expression" node.

Represents a function declaration or definition.

const ParmVarDecl * getParamDecl(unsigned i) const

bool isFunctionTemplateSpecialization() const

Determine whether this function is a function template specialization.

void setUsesSEHTry(bool UST)

bool isNoReturn() const

Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...

QualType getReturnType() const

FunctionTemplateDecl * getPrimaryTemplate() const

Retrieve the primary template that this function template specialization either specializes or was in...

const TemplateArgumentList * getTemplateSpecializationArgs() const

Retrieve the template arguments used to produce this function template specialization from the primar...

bool isConstexpr() const

Whether this is a (C++11) constexpr function or constexpr constructor.

bool isMain() const

Determines whether this function is "main", which is the entry point into an executable program.

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

bool isOverloadedOperator() const

Whether this function declaration represents an C++ overloaded operator, e.g., "operator+".

OverloadedOperatorKind getOverloadedOperator() const

getOverloadedOperator - Which C++ overloaded operator this function represents, if any.

QualType getDeclaredReturnType() const

Get the declared return type, which may differ from the actual return type if the return type is dedu...

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

Declaration of a template function.

FunctionType - C99 6.7.5.3 - Function Declarators.

static StringRef getNameForCallConv(CallingConv CC)

bool getNoReturnAttr() const

Determine whether this function type includes the GNU noreturn attribute.

QualType getReturnType() const

GotoStmt - This represents a direct goto.

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

IdentifierInfo & get(StringRef Name)

Return the identifier token info for the specified named identifier.

static IfStmt * Create(const ASTContext &Ctx, SourceLocation IL, IfStatementKind Kind, Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LPL, SourceLocation RPL, Stmt *Then, SourceLocation EL=SourceLocation(), Stmt *Else=nullptr)

Create an IfStmt.

ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...

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

static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)

Create implicit parameter.

IndirectGotoStmt - This represents an indirect goto.

static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)

Create a copy initialization.

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

Describes an entity that is being initialized.

static InitializedEntity InitializeResult(SourceLocation ReturnLoc, QualType Type)

Create the initialization entity for the result of a function.

static InitializedEntity InitializeRelatedResult(ObjCMethodDecl *MD, QualType Type)

Create the initialization entity for a related result.

unsigned allocateManglingNumber() const

static InitializedEntity InitializeVariable(VarDecl *Var)

Create the initialization entity for a variable.

static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)

Create the initialization entity for a parameter.

static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)

Returns a new integer literal with value 'V' and type 'type'.

Represents the declaration of a label.

void setLocStart(SourceLocation L)

LabelStmt * getStmt() const

void setStmt(LabelStmt *T)

bool isMSAsmLabel() const

LabelStmt - Represents a label, which has a substatement.

Represents the results of name lookup.

bool empty() const

Return true if no decls were found.

SourceLocation getKwLoc() const

Representation of a Microsoft __if_exists or __if_not_exists statement with a dependent name.

Represents a prvalue temporary that is written into memory so that a reference can bind to it.

Expr * getSubExpr() const

Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.

MemberExpr - [C99 6.5.2.3] Structure and Union Members.

This represents a decl that may have a name.

DeclarationName getDeclName() const

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

ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const

Determine if the declaration obeys the reserved identifier rules of the given language.

A C++ nested-name-specifier augmented with source location information.

NullStmt - This is the null statement ";": C99 6.8.3p3.

An expression that sends a message to the given Objective-C object or class.

ObjCMethodDecl - Represents an instance or class method declaration.

Represents a pointer to an Objective C object.

Expr * getSourceExpr() const

The source expression of an opaque value expression is the expression which originally generated the ...

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

@ CSK_Normal

Normal lookup.

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

static FindResult find(Expr *E)

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

const Expr * getSubExpr() const

Represents a parameter to a function.

ParsedAttributes - A collection of parsed attributes.

Wrapper for source info for pointers.

SourceLocation getStarLoc() const

IdentifierTable & getIdentifierTable()

PseudoObjectExpr - An expression which accesses a pseudo-object l-value.

ArrayRef< Expr * > semantics()

A (possibly-)qualified type.

bool isVolatileQualified() const

Determine whether this type is volatile-qualified.

QualType withConst() const

bool isTriviallyCopyConstructibleType(const ASTContext &Context) const

Return true if this is a trivially copyable type.

bool isNull() const

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

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.

unsigned getLocalCVRQualifiers() const

Retrieve the set of CVR (const-volatile-restrict) qualifiers local to this particular QualType instan...

bool isConstQualified() const

Determine whether this type is const-qualified.

@ OCL_Strong

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

Represents a struct/union/class.

static RecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl *PrevDecl=nullptr)

virtual void completeDefinition()

Note that the definition of this type is now complete.

void setCapturedRecord()

Mark the record as a record for captured variables in CapturedStmt construct.

ReturnStmt - This represents a return, optionally of an expression: return; return 4;.

void setRetValue(Expr *E)

static ReturnStmt * Create(const ASTContext &Ctx, SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)

Create a return statement.

static SEHExceptStmt * Create(const ASTContext &C, SourceLocation ExceptLoc, Expr *FilterExpr, Stmt *Block)

static SEHFinallyStmt * Create(const ASTContext &C, SourceLocation FinallyLoc, Stmt *Block)

Represents a __leave statement.

static SEHTryStmt * Create(const ASTContext &C, bool isCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)

Scope - A scope is a transient data structure that is used while parsing the program.

unsigned getDepth() const

Returns the depth of this scope. The translation-unit has scope depth 0.

bool Contains(const Scope &rhs) const

Returns if rhs has a higher scope depth than this.

LabelDecl * getPrecedingLabel() const

Get the label that precedes this scope.

unsigned getFlags() const

getFlags - Return the flags for this scope.

Scope * getContinueParent()

getContinueParent - Return the closest scope that a continue statement would be affected by.

bool isLoopScope() const

Return true if this scope is a loop.

bool isSEHTryScope() const

Determine whether this scope is a SEH '__try' block.

Scope * getBreakParent()

getBreakParent - Return the closest scope that a break statement would be affected by.

const Scope * getParent() const

getParent - Return the scope that this is nested in.

bool isBreakOrContinueScope() const

Determine whether this is a scope which can have 'break' or 'continue' statements embedded into it.

bool isConditionVarScope() const

bool isFunctionScope() const

isFunctionScope() - Return true if this scope is a function scope.

bool isOpenACCComputeConstructScope() const

Determine whether this scope is the statement associated with an OpenACC Compute construct directive.

bool isOpenMPLoopScope() const

Determine whether this scope is a loop having OpenMP loop directive attached.

@ SwitchScope

This is a scope that corresponds to a switch statement.

A generic diagnostic builder for errors which may or may not be deferred.

PartialDiagnostic PDiag(unsigned DiagID=0)

Build a partial diagnostic.

SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)

Emit a diagnostic.

CUDAFunctionTarget CurrentTarget()

Gets the CUDA target for the current context.

SemaDiagnosticBuilder DiagIfDeviceCode(SourceLocation Loc, unsigned DiagID)

Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as device c...

StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, Stmt *First, Expr *collection, SourceLocation RParenLoc)

StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body)

FinishObjCForCollectionStmt - Attach the body to a objective-C foreach statement.

bool inferObjCARCLifetime(ValueDecl *decl)

void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)

Check if the current region is an OpenMP loop region and if it is, mark loop control variable,...

void setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, unsigned Level)

Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) for FD based on DSA for the...

std::pair< VarDecl *, Expr * > get() const

RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...

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

ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)

Package the given type and TSI into a ParsedType.

SmallVector< Scope *, 2 > CurrentSEHFinally

Stack of active SEH __finally scopes. Can be empty.

LocalInstantiationScope * CurrentInstantiationScope

The current instantiation scope used to store local variables.

Scope * getCurScope() const

Retrieve the parser's current scope.

StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope, LabelDecl *Label, SourceLocation LabelLoc)

Definition SemaStmt.cpp:3366

void ProcessStmtAttributes(Stmt *Stmt, const ParsedAttributes &InAttrs, SmallVectorImpl< const Attr * > &OutAttrs)

Process the attributes before creating an attributed statement.

ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input, bool IsAfterAmp=false)

Unary Operators. 'Tok' is the token for the operator.

StmtResult BuildMSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, NestedNameSpecifierLoc QualifierLoc, DeclarationNameInfo NameInfo, Stmt *Nested)

Definition SemaStmt.cpp:4595

ExprResult IgnoredValueConversions(Expr *E)

IgnoredValueConversions - Given that an expression's result is syntactically ignored,...

@ LookupMemberName

Member name lookup, which finds the names of class/struct/union members.

bool ActOnCoroutineBodyStart(Scope *S, SourceLocation KwLoc, StringRef Keyword)

StmtResult BuildAttributedStmt(SourceLocation AttrsLoc, ArrayRef< const Attr * > Attrs, Stmt *SubStmt)

Definition SemaStmt.cpp:631

StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope)

Definition SemaStmt.cpp:4583

StmtResult ActOnForEachLValueExpr(Expr *E)

In an Objective C collection iteration statement: for (x in y) x can be an arbitrary l-value expressi...

Definition SemaStmt.cpp:2318

void ActOnForEachDeclStmt(DeclGroupPtrTy Decl)

Definition SemaStmt.cpp:85

void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, ExpressionEvaluationContextRecord::ExpressionKind Type=ExpressionEvaluationContextRecord::EK_Other)

ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, bool IsConstexpr=false)

CheckBooleanCondition - Diagnose problems involving the use of the given expression as a boolean cond...

@ Switch

An integral condition for a 'switch' statement.

SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes

Stack containing information about each of the nested function, block, and method scopes that are cur...

PoppedFunctionScopePtr PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP=nullptr, const Decl *D=nullptr, QualType BlockType=QualType())

Pop a function (or block or lambda or captured region) scope from the stack.

bool checkAndRewriteMustTailAttr(Stmt *St, const Attr &MTA)

Check whether the given statement can have musttail applied to it, issuing a diagnostic and returning...

Definition SemaStmt.cpp:660

StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope, LabelDecl *Label, SourceLocation LabelLoc)

Definition SemaStmt.cpp:3328

StmtResult ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, LabelDecl *TheDecl)

Definition SemaStmt.cpp:3223

StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, Scope *CurScope)

Definition SemaStmt.cpp:3914

void setFunctionHasBranchIntoScope()

ExprResult ActOnCaseExpr(SourceLocation CaseLoc, ExprResult Val)

Definition SemaStmt.cpp:485

StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue=true)

Definition SemaStmt.cpp:48

FieldDecl * BuildCaptureField(RecordDecl *RD, const sema::Capture &Capture)

Build a FieldDecl suitable to hold the given capture.

AssignConvertType CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, bool Diagnose=true, bool DiagnoseCFAudited=false, bool ConvertRHS=true)

Check assignment constraints for an assignment of RHS to LHSType.

StmtResult BuildIfStmt(SourceLocation IfLoc, IfStatementKind StatementKind, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc, Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal)

Definition SemaStmt.cpp:1032

FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const

Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...

ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)

Perform a contextual implicit conversion.

ExprResult UsualUnaryConversions(Expr *E)

UsualUnaryConversions - Performs various conversions that are common to most operators (C99 6....

void DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc)

Look for instances where it is likely the comma operator is confused with another operator.

void DiagnoseExceptionUse(SourceLocation Loc, bool IsTry)

Definition SemaStmt.cpp:4501

ExprResult CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond)

Definition SemaStmt.cpp:1108

bool DiagIfReachable(SourceLocation Loc, ArrayRef< const Stmt * > Stmts, const PartialDiagnostic &PD)

Conditionally issue a diagnostic based on the statements's reachability analysis.

void FinalizeDeclaration(Decl *D)

FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...

void ActOnCapturedRegionError()

Definition SemaStmt.cpp:4800

DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)

ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)

ASTContext & getASTContext() const

std::unique_ptr< sema::FunctionScopeInfo, PoppedFunctionScopeDeleter > PoppedFunctionScopePtr

ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)

void PopExpressionEvaluationContext()

StmtResult ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)

Definition SemaStmt.cpp:4518

ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)

ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.

ObjCMethodDecl * getCurMethodDecl()

getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...

DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)

ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, llvm::APSInt &Value, CCEKind CCE)

void setFunctionHasIndirectGoto()

ExprResult BuildCaptureInit(const sema::Capture &Capture, SourceLocation ImplicitCaptureLoc, bool IsOpenMPMapping=false)

Initialize the given capture with a suitable expression.

StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, Stmt *Body)

Definition SemaStmt.cpp:1296

NamedReturnInfo getNamedReturnInfo(Expr *&E, SimplerImplicitMoveMode Mode=SimplerImplicitMoveMode::Normal)

Determine whether the given expression might be move-eligible or copy-elidable in either a (co_)retur...

Definition SemaStmt.cpp:3408

void DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID)

DiagnoseUnusedExprResult - If the statement passed in is an expression whose result is unused,...

Definition SemaStmt.cpp:405

FPOptions & getCurFPFeatures()

Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, TranslationUnitKind TUKind=TU_Complete, CodeCompleteConsumer *CompletionConsumer=nullptr)

@ UPPC_Expression

An arbitrary expression.

const LangOptions & getLangOpts() const

StmtResult ActOnWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, ConditionResult Cond, SourceLocation RParenLoc, Stmt *Body)

Definition SemaStmt.cpp:1790

bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, UnexpandedParameterPackContext UPPC)

If the given type contains an unexpanded parameter pack, diagnose the error.

const LangOptions & LangOpts

sema::LambdaScopeInfo * getCurLambda(bool IgnoreNonLambdaCapturingScope=false)

Retrieve the current lambda scope info, if any.

void ActOnStartOfCompoundStmt(bool IsStmtExpr)

Definition SemaStmt.cpp:416

bool DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, SourceLocation ReturnLoc, Expr *RetExpr, const AutoType *AT)

Deduce the return type for a function from a returned expression, per C++1y [dcl.spec....

Definition SemaStmt.cpp:3798

void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool MightBeOdrUse)

Perform marking for a reference to an arbitrary declaration.

TypeLoc getReturnTypeLoc(FunctionDecl *FD) const

Definition SemaStmt.cpp:3791

StmtResult ActOnExprStmtError()

Definition SemaStmt.cpp:65

const VarDecl * getCopyElisionCandidate(NamedReturnInfo &Info, QualType ReturnType)

Updates given NamedReturnInfo's move-eligible and copy-elidable statuses, considering the function re...

Definition SemaStmt.cpp:3486

NamedDecl * getCurFunctionOrMethodDecl() const

getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...

StmtResult ActOnNullStmt(SourceLocation SemiLoc, bool HasLeadingEmptyMacro=false)

Definition SemaStmt.cpp:70

RecordDecl * CreateCapturedStmtRecordDecl(CapturedDecl *&CD, SourceLocation Loc, unsigned NumParams)

Definition SemaStmt.cpp:4619

void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams)

Definition SemaStmt.cpp:4702

sema::FunctionScopeInfo * getCurFunction() const

void PushCompoundScope(bool IsStmtExpr)

DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)

BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...

void DiagnoseAssignmentEnum(QualType DstType, QualType SrcType, Expr *SrcExpr)

DiagnoseAssignmentEnum - Warn if assignment to enum is a constant integer not in the range of enum va...

Definition SemaStmt.cpp:1728

StmtResult ActOnEndOfDeferStmt(Stmt *Body, Scope *CurScope)

Definition SemaStmt.cpp:3963

ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E)

bool findMacroSpelling(SourceLocation &loc, StringRef name)

Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...

void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, const Stmt *Body, unsigned DiagID)

Emit DiagID if statement located on StmtLoc has a suspicious null statement as a Body,...

void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody)

Warn if a for/while loop statement S, which is followed by PossibleBody, has a suspicious null statem...

ExprResult DefaultLvalueConversion(Expr *E)

DeclContext * CurContext

CurContext - This is the current declaration context of parsing.

DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name)

Retrieves the declaration name from a parsed unqualified-id.

void ActOnStartOfDeferStmt(SourceLocation DeferLoc, Scope *CurScope)

Definition SemaStmt.cpp:3954

bool isUnevaluatedContext() const

Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.

StmtResult ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, NamedReturnInfo &NRInfo, bool SupressSimplerImplicitMoves)

ActOnCapScopeReturnStmt - Utility routine to type-check return statements for capturing scopes.

Definition SemaStmt.cpp:3583

StmtResult ActOnCapturedRegionEnd(Stmt *S)

Definition SemaStmt.cpp:4815

StmtResult ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, Stmt *First, ConditionResult Second, FullExprArg Third, SourceLocation RParenLoc, Stmt *Body)

Definition SemaStmt.cpp:2253

StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, Expr *DestExp)

Definition SemaStmt.cpp:3238

ExprResult CheckPlaceholderExpr(Expr *E)

Check for operands with placeholder types and complain if found.

bool inTemplateInstantiation() const

Determine whether we are currently performing template instantiation.

SourceManager & getSourceManager() const

ExprResult PerformMoveOrCopyInitialization(const InitializedEntity &Entity, const NamedReturnInfo &NRInfo, Expr *Value, bool SupressSimplerImplicitMoves=false)

Perform the initialization of a potentially-movable value, which is the result of return value.

Definition SemaStmt.cpp:3543

void ActOnInitializerError(Decl *Dcl)

ActOnInitializerError - Given that there was an error parsing an initializer for the given declaratio...

StmtResult ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *InitStmt, Stmt *LoopVar, SourceLocation ColonLoc, Expr *Collection, SourceLocation RParenLoc, BuildForRangeKind Kind, ArrayRef< MaterializeTemporaryExpr * > LifetimeExtendTemps={})

ActOnCXXForRangeStmt - Check and build a C++11 for-range statement.

Definition SemaStmt.cpp:2431

bool isSFINAEContext() const

StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, bool AllowRecovery=false)

Definition SemaStmt.cpp:3986

ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr)

Binary Operators. 'Tok' is the token for the operator.

void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD, RecordDecl *RD, CapturedRegionKind K, unsigned OpenMPCaptureLevel=0)

void setFunctionHasMustTail()

void setFunctionHasBranchProtectedScope()

StmtResult ActOnFinishSEHFinallyBlock(SourceLocation Loc, Stmt *Block)

Definition SemaStmt.cpp:4576

StmtResult BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *InitStmt, SourceLocation ColonLoc, Stmt *RangeDecl, Stmt *Begin, Stmt *End, Expr *Cond, Expr *Inc, Stmt *LoopVarDecl, SourceLocation RParenLoc, BuildForRangeKind Kind, ArrayRef< MaterializeTemporaryExpr * > LifetimeExtendTemps={})

BuildCXXForRangeStmt - Build or instantiate a C++11 for-range statement.

Definition SemaStmt.cpp:2689

StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, SourceLocation WhileLoc, SourceLocation CondLParen, Expr *Cond, SourceLocation CondRParen)

Definition SemaStmt.cpp:1820

StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc)

Definition SemaStmt.cpp:1172

ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, AllowFoldKind CanFold=AllowFoldKind::No)

VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...

StmtResult ActOnMSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, CXXScopeSpec &SS, UnqualifiedId &Name, Stmt *Nested)

Definition SemaStmt.cpp:4607

@ PotentiallyEvaluated

The current expression is potentially evaluated at run time, which means that code may be generated t...

@ ImmediateFunctionContext

In addition of being constant evaluated, the current expression occurs in an immediate function conte...

StmtResult ActOnSEHExceptBlock(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)

Definition SemaStmt.cpp:4556

void ActOnAfterCompoundStatementLeadingPragmas()

Definition SemaStmt.cpp:420

StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)

Definition SemaStmt.cpp:75

bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)

Ensure that the type T is a complete type.

void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl, ArrayRef< Decl * > Fields, SourceLocation LBrac, SourceLocation RBrac, const ParsedAttributesView &AttrList)

bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)

Perform qualified name lookup into a given context.

void DiscardCleanupsInEvaluationContext()

SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts

A stack of expression evaluation contexts.

void PushDeclContext(Scope *S, DeclContext *DC)

Set the current declaration context until it gets popped.

StmtResult ActOnAttributedStmt(const ParsedAttributes &AttrList, Stmt *SubStmt)

Definition SemaStmt.cpp:648

SourceManager & SourceMgr

DiagnosticsEngine & Diags

void ActOnStartSEHFinallyBlock()

Definition SemaStmt.cpp:4568

ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)

void ActOnAbortSEHFinallyBlock()

Definition SemaStmt.cpp:4572

friend class InitializationSequence

void diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals, SourceLocation FallbackLoc, SourceLocation ConstQualLoc=SourceLocation(), SourceLocation VolatileQualLoc=SourceLocation(), SourceLocation RestrictQualLoc=SourceLocation(), SourceLocation AtomicQualLoc=SourceLocation(), SourceLocation UnalignedQualLoc=SourceLocation())

void ActOnDeferStmtError(Scope *CurScope)

Definition SemaStmt.cpp:3958

QualType SubstAutoTypeDependent(QualType TypeWithAuto)

@ BFRK_Check

Determining whether a for-range statement could be built.

@ BFRK_Build

Initial building of a for-range statement.

@ BFRK_Rebuild

Instantiation or recovery rebuild of a for-range statement.

StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl, Stmt *HandlerBlock)

ActOnCXXCatchBlock - Takes an exception declaration and a handler block and creates a proper catch ha...

Definition SemaStmt.cpp:4273

void ActOnCaseStmtBody(Stmt *CaseStmt, Stmt *SubStmt)

ActOnCaseStmtBody - This installs a statement as the body of a case.

Definition SemaStmt.cpp:563

void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)

AddInitializerToDecl - Adds the initializer Init to the declaration dcl.

bool DiagnoseAssignmentResult(AssignConvertType ConvTy, SourceLocation Loc, QualType DstType, QualType SrcType, Expr *SrcExpr, AssignmentAction Action, bool *Complained=nullptr)

DiagnoseAssignmentResult - Emit a diagnostic, if required, for the assignment conversion type specifi...

SemaDiagnosticBuilder targetDiag(SourceLocation Loc, unsigned DiagID, const FunctionDecl *FD=nullptr)

ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, ArrayRef< Expr * > SubExprs, QualType T=QualType())

Attempts to produce a RecoveryExpr after some AST node cannot be created.

StmtResult ActOnIfStmt(SourceLocation IfLoc, IfStatementKind StatementKind, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc, Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal)

Definition SemaStmt.cpp:950

std::string getTemplateArgumentBindingsText(const TemplateParameterList *Params, const TemplateArgumentList &Args)

Produces a formatted string that describes the binding of template parameters to template arguments.

ExprResult ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, bool IsType, void *TyOrEx, SourceRange ArgRange)

ActOnUnaryExprOrTypeTraitExpr - Handle sizeof(type) and sizeof expr and the same for alignof and __al...

ForRangeStatus BuildForRangeBeginEndCall(SourceLocation Loc, SourceLocation RangeLoc, const DeclarationNameInfo &NameInfo, LookupResult &MemberLookup, OverloadCandidateSet *CandidateSet, Expr *Range, ExprResult *CallExpr)

Build a call to 'begin' or 'end' for a C++11 for-range statement.

sema::CompoundScopeInfo & getCurCompoundScope() const

Definition SemaStmt.cpp:432

TemplateDeductionResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *Initializer, QualType &Result, sema::TemplateDeductionInfo &Info, bool DependentDeduction=false, bool IgnoreConstraints=false, TemplateSpecCandidateSet *FailedTSC=nullptr)

Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6)

void ActOnFinishOfCompoundStmt()

Definition SemaStmt.cpp:428

StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)

Definition SemaStmt.cpp:436

bool IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, bool AllowMask) const

IsValueInFlagEnum - Determine if a value is allowed as part of a flag enum.

StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, SourceLocation ColonLoc, Stmt *SubStmt)

Definition SemaStmt.cpp:588

StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, ArrayRef< Stmt * > Handlers)

ActOnCXXTryBlock - Takes a try compound-statement and a number of handlers and creates a try statemen...

Definition SemaStmt.cpp:4393

OpaquePtr< DeclGroupRef > DeclGroupPtrTy

StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, Stmt *SubStmt, Scope *CurScope)

Definition SemaStmt.cpp:568

StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHS, SourceLocation DotDotDotLoc, ExprResult RHS, SourceLocation ColonLoc)

Definition SemaStmt.cpp:532

SmallVector< std::pair< Scope *, SourceLocation >, 2 > CurrentDefer

Stack of '_Defer' statements that are currently being parsed, as well as the locations of their '_Def...

StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body)

FinishCXXForRangeStmt - Attach the body to a C++0x for-range statement.

Definition SemaStmt.cpp:3205

ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)

Encodes a location in the source.

bool isValid() const

Return true if this is a valid SourceLocation object.

SourceLocation getLocWithOffset(IntTy Offset) const

Return a source location with the specified offset from this SourceLocation.

bool isMacroBodyExpansion(SourceLocation Loc) const

Tests whether the given source location represents the expansion of a macro body.

bool isInSystemMacro(SourceLocation loc) const

Returns whether Loc is expanded from a macro in a system header.

bool isInSystemHeader(SourceLocation Loc) const

Returns if a SourceLocation is in a system header.

A trivial tuple used to represent a source range.

SourceLocation getBegin() const

Stmt - This represents one statement.

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

static std::tuple< bool, const Attr *, const Attr * > determineLikelihoodConflict(const Stmt *Then, const Stmt *Else)

static const Attr * getLikelihoodAttr(const Stmt *S)

SourceLocation getBeginLoc() const LLVM_READONLY

SwitchStmt - This represents a 'switch' stmt.

static SwitchStmt * Create(const ASTContext &Ctx, Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LParenLoc, SourceLocation RParenLoc)

Create a switch statement.

SwitchCase * getSwitchCaseList()

DeclStmt * getConditionVariableDeclStmt()

If this SwitchStmt has a condition variable, return the faux DeclStmt associated with the creation of...

void setAllEnumCasesCovered()

Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a switch over an enum value then ...

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

void startDefinition()

Starts the definition of this tag declaration.

TemplateSpecCandidateSet - A set of generalized overload candidates, used in template specializations...

void NoteCandidates(Sema &S, SourceLocation Loc)

NoteCandidates - When no template specialization match is found, prints diagnostic messages containin...

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

QualType getType() const

Get the type for which this source info wrapper provides information.

T castAs() const

Convert to the specified TypeLoc type, asserting that this TypeLoc is of the desired type.

T getAsAdjusted() const

Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...

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

Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...

bool isRValueReferenceType() const

CXXRecordDecl * getAsCXXRecordDecl() const

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

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

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.

AutoType * getContainedAutoType() const

Get the AutoType whose type will be deduced for a variable with an initializer of this type.

bool isSpecificBuiltinType(unsigned K) const

Test for a particular builtin type.

bool isDependentType() const

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

bool containsErrors() const

Whether this type is an error type.

EnumDecl * castAsEnumDecl() const

const ArrayType * getAsArrayTypeUnsafe() const

A variant of getAs<> for array types which silently discards qualifiers from the outermost type.

bool isUndeducedType() const

Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...

bool isObjectType() const

Determine whether this type is an object type.

bool isIncompleteType(NamedDecl **Def=nullptr) const

Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...

const T * getAsCanonical() const

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

TypeClass getTypeClass() const

bool isCanonicalUnqualified() const

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

const T * getAs() const

Member-template getAs'.

bool isRecordType() const

UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...

Expr * getSubExpr() const

Represents a C++ unqualified-id that has been parsed.

void setType(QualType newType)

Represents a variable declaration or definition.

static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)

SourceRange getSourceRange() const override LLVM_READONLY

Source range that this declaration covers.

bool hasGlobalStorage() const

Returns true for all variables that do not have local storage.

bool isExceptionVariable() const

Determine whether this variable is the exception variable in a C++ catch statememt or an Objective-C ...

const Expr * getInit() const

bool hasLocalStorage() const

Returns true if a variable with function scope is a non-static local variable.

bool isLocalVarDecl() const

Returns true for local variable declarations other than parameters.

bool hasDependentAlignment() const

Determines if this variable's alignment is dependent.

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

static WhileStmt * Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, Stmt *Body, SourceLocation WL, SourceLocation LParenLoc, SourceLocation RParenLoc)

Create a while statement.

ValueDecl * getVariable() const

bool isVariableCapture() const

SourceLocation getLocation() const

Retrieve the location at which this variable was captured.

bool isVLATypeCapture() const

bool isThisCapture() const

bool isReferenceCapture() const

Retains information about a captured region.

unsigned short OpenMPLevel

unsigned short CapRegionKind

The kind of captured region.

RecordDecl * TheRecordDecl

The captured record type.

CapturedDecl * TheCapturedDecl

The CapturedDecl for this statement.

QualType ReturnType

ReturnType - The target type of return statements in this context, or null if unknown.

SmallVector< Capture, 4 > Captures

Captures - The captures.

bool HasImplicitReturnType

Contains information about the compound statement currently being parsed.

FPOptions InitialFPFeatures

FP options at the beginning of the compound statement, prior to any pragma.

void setHasEmptyLoopBodies()

Retains information about a function, method, or block that is currently being parsed.

llvm::PointerIntPair< SwitchStmt *, 1, bool > SwitchInfo

A SwitchStmt, along with a flag indicating if its list of case statements is incomplete (because we d...

SourceLocation FirstCXXOrObjCTryLoc

First C++ 'try' or ObjC @try statement in the current function.

SourceLocation FirstCoroutineStmtLoc

First coroutine statement in the current function.

enum clang::sema::FunctionScopeInfo::@340304006310276167163023075110222134352007243353 FirstTryType

StringRef getFirstCoroutineStmtKeyword() const

SourceLocation FirstReturnLoc

First 'return' statement in the current function.

SourceLocation FirstSEHTryLoc

First SEH '__try' statement in the current function.

void setHasCXXTry(SourceLocation TryLoc)

SmallVector< CompoundScopeInfo, 4 > CompoundScopes

The stack of currently active compound statement scopes in the function.

void setHasSEHTry(SourceLocation TryLoc)

SmallVector< SwitchInfo, 8 > SwitchStack

SwitchStack - This is the current set of active switch statements in the block.

CXXMethodDecl * CallOperator

The lambda's compiler-generated operator().

Provides information about an attempted template argument deduction, whose success or failure was des...

TemplateArgument SecondArg

The second template argument to which the template argument deduction failure refers.

TemplateArgument FirstArg

The first template argument to which the template argument deduction failure refers.

Defines the clang::TargetInfo interface.

const internal::VariadicAllOfMatcher< Type > type

Matches Types in the clang AST.

const internal::VariadicAllOfMatcher< Decl > decl

Matches declarations.

bool This(InterpState &S, CodePtr OpPC)

bool Cast(InterpState &S, CodePtr OpPC)

void checkExprLifetimeMustTailArg(Sema &SemaRef, const InitializedEntity &Entity, Expr *Init)

Check that the lifetime of the given expr (and its subobjects) is sufficient, assuming that it is pas...

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)

Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)

if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))

@ OR_Deleted

Succeeded, but refers to a deleted function.

@ OR_Success

Overload resolution succeeded.

bool isReservedInAllContexts(ReservedIdentifierStatus Status)

Determine whether an identifier is reserved in all contexts.

IfStatementKind

In an if statement, this denotes whether the statement is a constexpr or consteval if statement.

Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)

Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...

@ RQ_None

No ref-qualifier was provided.

@ OCD_AllCandidates

Requests that all candidates be shown.

@ Seq

'seq' clause, allowed on 'loop' and 'routine' directives.

bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)

SmallVector< Attr *, 4 > AttrVec

AttrVec - A vector of Attr, which is how they are stored on the AST.

nullptr

This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...

CapturedRegionKind

The different kinds of captured statement.

@ Result

The result type of a method or function.

const FunctionProtoType * T

AssignConvertType

AssignConvertType - All of the 'assignment' semantic checks return this enum to indicate whether the ...

bool hasArmZT0State(const FunctionDecl *FD)

Returns whether the given FunctionDecl has Arm ZT0 state.

@ Struct

The "struct" keyword.

@ Type

The name was classified as a type.

bool isLambdaConversionOperator(CXXConversionDecl *C)

std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt

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

@ VK_XValue

An x-value expression is a reference to an object with independent storage but which can be "moved",...

@ VK_LValue

An l-value expression is a reference to an object with independent storage.

Expr * IgnoreParensSingleStep(Expr *E)

Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)

DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor

TemplateDeductionResult

Describes the result of template argument deduction.

@ Success

Template argument deduction was successful.

@ Inconsistent

Template argument deduction produced inconsistent deduced values for the given template parameter.

@ AlreadyDiagnosed

Some error which was already diagnosed.

U cast(CodeGen::Address addr)

@ CaseValue

Expression in a case label.

bool IsArmStreamingFunction(const FunctionDecl *FD, bool IncludeLocallyStreaming)

Returns whether the given FunctionDecl has an __arm[_locally]_streaming attribute.

ActionResult< Expr * > ExprResult

@ CapturedContext

Parameter for captured context.

ActionResult< Stmt * > StmtResult

bool hasArmZAState(const FunctionDecl *FD)

Returns whether the given FunctionDecl has Arm ZA state.

DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...

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

@ MoveEligibleAndCopyElidable

bool isMoveEligible() const

bool isCopyElidable() const

const VarDecl * Candidate

static CatchHandlerType getEmptyKey()

Definition SemaStmt.cpp:4327

static CatchHandlerType getTombstoneKey()

Definition SemaStmt.cpp:4332

static unsigned getHashValue(const CatchHandlerType &Base)

Definition SemaStmt.cpp:4337

static bool isEqual(const CatchHandlerType &LHS, const CatchHandlerType &RHS)

Definition SemaStmt.cpp:4341