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->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 && (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 .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 (.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 .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
1164 if (->isTypeDependent() &&
1165 ->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 .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);
1830
1835
1836
1838 .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 .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 (.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 (.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 && ->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 .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 (->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 (.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