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/STLForwardCompat.h"
43#include "llvm/ADT/SmallVector.h"
44#include "llvm/ADT/StringExtras.h"
45
46using namespace clang;
47using namespace sema;
48
52
56
57
58
59
60
61
63}
64
65
69}
70
72 bool HasLeadingEmptyMacro) {
73 return new (Context) NullStmt(SemiLoc, HasLeadingEmptyMacro);
74}
75
79
80
82
84}
85
88
89
90
92 return;
93
95 if ( || decl->isInvalidDecl())
96 return;
97
98
100 if (!var) {
101 Diag(decl->getLocation(), diag::err_non_variable_decl_in_for);
102 decl->setInvalidDecl();
103 return;
104 }
105
106
107
108 var->setInit(nullptr);
109
110
111
112
115
116
117
118
120
121 var->setType(type.withConst());
122 var->setARCPseudoStrong(true);
123 }
124 }
125}
126
127
128
129
130
131
134 bool CanAssign;
135 enum { Equality, Inequality, Relational, ThreeWay } Kind;
136
137 if (const BinaryOperator *Op = dyn_cast(E)) {
138 if (!Op->isComparisonOp())
139 return false;
140
141 if (Op->getOpcode() == BO_EQ)
142 Kind = Equality;
143 else if (Op->getOpcode() == BO_NE)
144 Kind = Inequality;
145 else if (Op->getOpcode() == BO_Cmp)
146 Kind = ThreeWay;
147 else {
148 assert(Op->isRelationalOp());
149 Kind = Relational;
150 }
151 Loc = Op->getOperatorLoc();
152 CanAssign = Op->getLHS()->IgnoreParenImpCasts()->isLValue();
153 } else if (const CXXOperatorCallExpr *Op = dyn_cast(E)) {
154 switch (Op->getOperator()) {
155 case OO_EqualEqual:
156 Kind = Equality;
157 break;
158 case OO_ExclaimEqual:
159 Kind = Inequality;
160 break;
161 case OO_Less:
162 case OO_Greater:
163 case OO_GreaterEqual:
164 case OO_LessEqual:
165 Kind = Relational;
166 break;
167 case OO_Spaceship:
168 Kind = ThreeWay;
169 break;
170 default:
171 return false;
172 }
173
174 Loc = Op->getOperatorLoc();
175 CanAssign = Op->getArg(0)->IgnoreParenImpCasts()->isLValue();
176 } else {
177
178 return false;
179 }
180
181
182
184 return false;
185
186 S.Diag(Loc, diag::warn_unused_comparison)
188
189
190
191 if (CanAssign) {
192 if (Kind == Inequality)
193 S.Diag(Loc, diag::note_inequality_comparison_to_or_assign)
195 else if (Kind == Equality)
196 S.Diag(Loc, diag::note_equality_comparison_to_assign)
198 }
199
200 return true;
201}
202
206 if (!A)
207 return false;
208 StringRef Msg = A->getMessage();
209
210 if (Msg.empty()) {
211 if (OffendingDecl)
212 return S.Diag(Loc, diag::warn_unused_return_type)
213 << IsCtor << A << OffendingDecl << false << R1 << R2;
214 if (IsCtor)
215 return S.Diag(Loc, diag::warn_unused_constructor)
216 << A << false << R1 << R2;
217 return S.Diag(Loc, diag::warn_unused_result) << A << false << R1 << R2;
218 }
219
220 if (OffendingDecl)
221 return S.Diag(Loc, diag::warn_unused_return_type)
222 << IsCtor << A << OffendingDecl << true << Msg << R1 << R2;
223 if (IsCtor)
224 return S.Diag(Loc, diag::warn_unused_constructor)
225 << A << true << Msg << R1 << R2;
226 return S.Diag(Loc, diag::warn_unused_result) << A << true << Msg << R1 << R2;
227}
228
229namespace {
230
231
232
233
234
235void DiagnoseUnused(Sema &S, const Expr *E, std::optional DiagID) {
236 bool NoDiscardOnly = !DiagID.has_value();
237
238
239
241 return;
242
244
245
246
247
248
251
252 const Expr *WarnExpr;
256 return;
257
258 if (!NoDiscardOnly) {
259
260
261
262
264 return;
265
266
267
268
272 return;
273 }
274 }
275
276
277
278
279 if (const FullExpr *Temps = dyn_cast(E))
280 E = Temps->getSubExpr();
282 E = TempExpr->getSubExpr();
283
285 return;
286
287 E = WarnExpr;
288 if (const auto *Cast = dyn_cast(E))
289 if (Cast->getCastKind() == CK_NoOp ||
290 Cast->getCastKind() == CK_ConstructorConversion ||
291 Cast->getCastKind() == CK_IntegralCast)
292 E = Cast->getSubExpr()->IgnoreImpCasts();
293
294 if (const CallExpr *CE = dyn_cast(E)) {
296 return;
297
298 auto [OffendingDecl, A] = CE->getUnusedResultAttr(S.Context);
300 cast_or_null(A), Loc, R1, R2,
301 false))
302 return;
303
304
305
306
307
308 if (const Decl *FD = CE->getCalleeDecl()) {
309 if (ShouldSuppress)
310 return;
311 if (FD->hasAttr()) {
312 S.Diag(Loc, diag::warn_unused_call) << R1 << R2 << "pure";
313 return;
314 }
315 if (FD->hasAttr()) {
316 S.Diag(Loc, diag::warn_unused_call) << R1 << R2 << "const";
317 return;
318 }
319 }
320 } else if (const auto *CE = dyn_cast(E)) {
322 const NamedDecl *OffendingDecl = nullptr;
323 const auto *A = Ctor->getAttr();
324 if (!A) {
325 OffendingDecl = Ctor->getParent();
326 A = OffendingDecl->getAttr();
327 }
329 true))
330 return;
331 }
332 } else if (const auto *ILE = dyn_cast(E)) {
333 if (const TagDecl *TD = ILE->getType()->getAsTagDecl()) {
334
336 R2, false))
337 return;
338 }
339 } else if (ShouldSuppress)
340 return;
341
342 E = WarnExpr;
343 if (const ObjCMessageExpr *ME = dyn_cast(E)) {
344 if (S.getLangOpts().ObjCAutoRefCount && ME->isDelegateInitCall()) {
345 S.Diag(Loc, diag::err_arc_unused_init_message) << R1;
346 return;
347 }
349 if (MD) {
351 Loc, R1, R2,
352 false))
353 return;
354 }
355 } else if (const PseudoObjectExpr *POE = dyn_cast(E)) {
356 const Expr *Source = POE->getSyntacticForm();
357
358 if (S.LangOpts.OpenMP && isa(Source) &&
359 POE->getNumSemanticExprs() == 1 &&
360 isa(POE->getSemanticExpr(0)))
361 return DiagnoseUnused(S, POE->getSemanticExpr(0), DiagID);
362 if (isa(Source))
363 DiagID = diag::warn_unused_container_subscript_expr;
364 else if (isa(Source))
365 DiagID = diag::warn_unused_property_expr;
367 = dyn_cast(E)) {
368 const Expr *E = FC->getSubExpr();
370 E = TE->getSubExpr();
371 if (isa(E))
372 return;
374 if (const CXXRecordDecl *RD = CE->getType()->getAsCXXRecordDecl())
375 if (!RD->getAttr())
376 return;
377 }
378
379 if (NoDiscardOnly)
380 return;
381
382
383 if (const CStyleCastExpr *CE = dyn_cast(E)) {
386
387
390
391 S.Diag(Loc, diag::warn_unused_voidptr)
393 return;
394 }
395 }
396
397
398
401 S.Diag(Loc, diag::warn_unused_volatile) << R1 << R2;
402 return;
403 }
404
405
406
407
408 if (DiagID == diag::warn_unused_comma_left_operand && S.isSFINAEContext())
409 return;
410
412 S.PDiag(*DiagID) << R1 << R2);
413}
414}
415
417 DiagnoseUnused(*this, E, std::nullopt);
418}
419
421 if (const LabelStmt *Label = dyn_cast_if_present(S))
422 S = Label->getSubStmt();
423
424 const Expr *E = dyn_cast_if_present(S);
425 if ()
426 return;
427
428 DiagnoseUnused(*this, E, DiagID);
429}
430
433}
434
438 assert(FSI);
440 }
441}
442
445}
446
449}
450
453 const unsigned NumElts = Elts.size();
454
455
456
457
458 const unsigned MixedDeclsCodeID = getLangOpts().C99
459 ? diag::warn_mixed_decls_code
460 : diag::ext_mixed_decls_code;
462
463 unsigned i = 0;
464
465 for (; i != NumElts && isa(Elts[i]); ++i)
466 ;
467
468
469 for (; i != NumElts && !isa(Elts[i]); ++i)
470 ;
471
472 if (i != NumElts) {
473 Decl *D = *cast(Elts[i])->decl_begin();
475 }
476 }
477
478
479
480
483 for (unsigned i = 0; i != NumElts - 1; ++i)
485 }
486
487
488
489
490
495
497}
498
501 if (!Val.get())
502 return Val;
503
506
507
508
512
513 Expr *CondExpr =
515 if (!CondExpr)
518
519 auto CheckAndFinish = [&](Expr *E) {
522
524
525
526 llvm::APSInt TempVal;
529 }
530
540 return ER;
541 };
542
544 Val, nullptr, false,
545 CheckAndFinish);
546 if (Converted.get() == Val.get())
547 Converted = CheckAndFinish(Val.get());
548 return Converted;
549}
550
555 assert((LHSVal.isInvalid() || LHSVal.get()) && "missing LHS value");
558 "missing RHS value");
559
561 Diag(CaseLoc, diag::err_case_not_in_switch);
563 }
564
568 }
569
572 Diag(CaseLoc, diag::err_acc_branch_in_out_compute_construct)
573 << 0 << 1;
575 }
576
578 CaseLoc, DotDotDotLoc, ColonLoc);
580 return CS;
581}
582
584 cast(S)->setSubStmt(SubStmt);
585}
586
589 Stmt *SubStmt, Scope *CurScope) {
591 Diag(DefaultLoc, diag::err_default_not_in_switch);
592 return SubStmt;
593 }
594
597 Diag(DefaultLoc, diag::err_acc_branch_in_out_compute_construct)
598 << 0 << 1;
600 }
601
604 return DS;
605}
606
610
611 if (TheDecl->getStmt()) {
612 Diag(IdentLoc, diag::err_redefinition_of_label) << TheDecl->getDeclName();
613 Diag(TheDecl->getLocation(), diag::note_previous_definition);
614 return SubStmt;
615 }
616
620 Diag(IdentLoc, diag::warn_reserved_extern_symbol)
621 << TheDecl << static_cast(Status);
622
623
624
625 if (getCurScope()->isInOpenACCComputeConstructScope())
627
628
629
630
631
632 if (isa(SubStmt)) {
633 Diag(SubStmt->getBeginLoc(), diag::err_acc_update_as_body) << 4;
635 }
636
637
643
644
646 }
647 }
648 return LS;
649}
650
653 Stmt *SubStmt) {
654
655
656 for (const auto *A : Attrs) {
657 if (A->getKind() == attr::MustTail) {
659 return SubStmt;
660 }
662 }
663 }
664
666}
667
669 Stmt *SubStmt) {
672 if (!SemanticAttrs.empty())
674
675
676
677 return SubStmt;
678}
679
681 ReturnStmt *R = cast(St);
683
685
686 return true;
687
688 if (!checkMustTailAttr(St, MTA))
689 return false;
690
691
692
693
694 auto IgnoreImplicitAsWritten = [](Expr *E) -> Expr * {
697 };
698
699
700
702 return true;
703}
704
705bool Sema::checkMustTailAttr(const Stmt *St, const Attr &MTA) {
707 "musttail cannot be checked from a dependent context");
708
709
710 auto IgnoreParenImplicitAsWritten = [](const Expr *E) -> const Expr * {
714 };
715
716 const Expr *E = cast(St)->getRetValue();
717 const auto *CE = dyn_cast_or_null(IgnoreParenImplicitAsWritten(E));
718
719 if (!CE) {
720 Diag(St->getBeginLoc(), diag::err_musttail_needs_call) << &MTA;
721 return false;
722 }
723
724 if (const auto *EWC = dyn_cast(E)) {
725 if (EWC->cleanupsHaveSideEffects()) {
726 Diag(St->getBeginLoc(), diag::err_musttail_needs_trivial_args) << &MTA;
727 return false;
728 }
729 }
730
731
732
733 struct FuncType {
734 enum {
735 ft_non_member,
736 ft_static_member,
737 ft_non_static_member,
738 ft_pointer_to_member,
739 } MemberType = ft_non_member;
740
744 } CallerType, CalleeType;
745
746 auto GetMethodType = [this, St, MTA](const CXXMethodDecl *CMD, FuncType &Type,
747 bool IsCallee) -> bool {
748 if (isa<CXXConstructorDecl, CXXDestructorDecl>(CMD)) {
749 Diag(St->getBeginLoc(), diag::err_musttail_structors_forbidden)
750 << IsCallee << isa(CMD);
751 if (IsCallee)
752 Diag(CMD->getBeginLoc(), diag::note_musttail_structors_forbidden)
753 << isa(CMD);
754 Diag(MTA.getLocation(), diag::note_tail_call_required) << &MTA;
755 return false;
756 }
757 if (CMD->isStatic())
758 Type.MemberType = FuncType::ft_static_member;
759 else {
760 Type.This = CMD->getFunctionObjectParameterType();
761 Type.MemberType = FuncType::ft_non_static_member;
762 }
764 return true;
765 };
766
767 const auto *CallerDecl = dyn_cast(CurContext);
768
769
770 if (!CallerDecl) {
774 else if (isa(CurContext))
776 else
778 Diag(St->getBeginLoc(), diag::err_musttail_forbidden_from_this_context)
780 return false;
781 } else if (const auto *CMD = dyn_cast(CurContext)) {
782
783 if (!GetMethodType(CMD, CallerType, false))
784 return false;
785 } else {
786
787 CallerType.Func = CallerDecl->getType()->getAs<FunctionProtoType>();
788 }
789
791 const auto *CalleeBinOp = dyn_cast(CalleeExpr);
793 ? CE->getCalleeDecl()->getBeginLoc()
795
796
798 dyn_cast_or_null(CE->getCalleeDecl())) {
799
800 if (!GetMethodType(CMD, CalleeType, true))
801 return false;
802 } else if (CalleeBinOp && CalleeBinOp->isPtrMemOp()) {
803
804 const auto *MPT =
806 CalleeType.This = QualType(MPT->getClass(), 0);
807 CalleeType.Func = MPT->getPointeeType()->castAs<FunctionProtoType>();
808 CalleeType.MemberType = FuncType::ft_pointer_to_member;
809 } else if (isa(CalleeExpr)) {
810 Diag(St->getBeginLoc(), diag::err_musttail_structors_forbidden)
811 << 1 << 1;
812 Diag(MTA.getLocation(), diag::note_tail_call_required) << &MTA;
813 return false;
814 } else {
815
816 CalleeType.Func =
818 }
819
820
821 if (!CalleeType.Func || !CallerType.Func) {
822 Diag(St->getBeginLoc(), diag::err_musttail_needs_prototype) << &MTA;
823 if (!CalleeType.Func && CE->getDirectCallee()) {
824 Diag(CE->getDirectCallee()->getBeginLoc(),
825 diag::note_musttail_fix_non_prototype);
826 }
827 if (!CallerType.Func)
828 Diag(CallerDecl->getBeginLoc(), diag::note_musttail_fix_non_prototype);
829 return false;
830 }
831
832
833
834
835
836
837
838
839 if (CallerType.Func->getCallConv() != CalleeType.Func->getCallConv()) {
840 if (const auto *ND = dyn_cast_or_null(CE->getCalleeDecl()))
841 Diag(St->getBeginLoc(), diag::err_musttail_callconv_mismatch)
842 << true << ND->getDeclName();
843 else
844 Diag(St->getBeginLoc(), diag::err_musttail_callconv_mismatch) << false;
845 Diag(CalleeLoc, diag::note_musttail_callconv_mismatch)
848 Diag(MTA.getLocation(), diag::note_tail_call_required) << &MTA;
849 return false;
850 }
851
852 if (CalleeType.Func->isVariadic() || CallerType.Func->isVariadic()) {
853 Diag(St->getBeginLoc(), diag::err_musttail_no_variadic) << &MTA;
854 return false;
855 }
856
857 const auto *CalleeDecl = CE->getCalleeDecl();
858 if (CalleeDecl && CalleeDecl->hasAttr()) {
859 Diag(St->getBeginLoc(), diag::err_musttail_no_return) << &MTA;
860 return false;
861 }
862
863
864 if (CallerType.This.isNull() != CalleeType.This.isNull()) {
865 if (const auto *ND = dyn_cast_or_null(CE->getCalleeDecl())) {
866 Diag(St->getBeginLoc(), diag::err_musttail_member_mismatch)
867 << CallerType.MemberType << CalleeType.MemberType << true
868 << ND->getDeclName();
869 Diag(CalleeLoc, diag::note_musttail_callee_defined_here)
870 << ND->getDeclName();
871 } else
872 Diag(St->getBeginLoc(), diag::err_musttail_member_mismatch)
873 << CallerType.MemberType << CalleeType.MemberType << false;
874 Diag(MTA.getLocation(), diag::note_tail_call_required) << &MTA;
875 return false;
876 }
877
878 auto CheckTypesMatch = [this](FuncType CallerType, FuncType CalleeType,
880 enum {
885 };
886
888 unsigned Select) -> bool {
891 return false;
892 }
893 return true;
894 };
895
896 if (!CallerType.This.isNull() &&
898 return false;
899
900 if (!DoTypesMatch(CallerType.Func->getReturnType(),
902 return false;
903
904 if (CallerType.Func->getNumParams() != CalleeType.Func->getNumParams()) {
906 << CalleeType.Func->getNumParams();
907 return false;
908 }
909
912 size_t N = CallerType.Func->getNumParams();
913 for (size_t I = 0; I < N; I++) {
914 if (!DoTypesMatch(CalleeParams[I], CallerParams[I],
916 PD << static_cast(I) + 1;
917 return false;
918 }
919 }
920
921 return true;
922 };
923
925 if (!CheckTypesMatch(CallerType, CalleeType, PD)) {
926 if (const auto *ND = dyn_cast_or_null(CE->getCalleeDecl()))
928 << true << ND->getDeclName();
929 else
930 Diag(St->getBeginLoc(), diag::err_musttail_mismatch) << false;
931 Diag(CalleeLoc, PD);
932 Diag(MTA.getLocation(), diag::note_tail_call_required) << &MTA;
933 return false;
934 }
935
936
937
938
939 for (auto ArgExpr : CE->arguments()) {
941 Context, ArgExpr->getType(), false);
943 }
944
945 return true;
946}
947
948namespace {
951 Sema &SemaRef;
952public:
953 CommaVisitor(Sema &SemaRef) : Inherited(SemaRef.Context), SemaRef(SemaRef) {}
955 if (E->getOpcode() == BO_Comma)
958 }
959};
960}
961
967 Stmt *elseStmt) {
970
971 bool ConstevalOrNegatedConsteval =
974
975 Expr *CondExpr = Cond.get().second;
976 assert((CondExpr || ConstevalOrNegatedConsteval) &&
977 "If statement: missing condition");
978
981 CommaVisitor(*this).Visit(CondExpr);
982
983 if (!ConstevalOrNegatedConsteval && !elseStmt)
985
986 if (ConstevalOrNegatedConsteval ||
988 auto DiagnoseLikelihood = [&](const Stmt *S) {
991 diag::warn_attribute_has_no_effect_on_compile_time_if)
992 << A << ConstevalOrNegatedConsteval << A->getRange();
994 diag::note_attribute_has_no_effect_on_compile_time_if_here)
995 << ConstevalOrNegatedConsteval
996 << SourceRange(IfLoc, (ConstevalOrNegatedConsteval
998 : LParenLoc)
1000 }
1001 };
1002 DiagnoseLikelihood(thenStmt);
1003 DiagnoseLikelihood(elseStmt);
1004 } else {
1005 std::tuple<bool, const Attr *, const Attr *> LHC =
1007 if (std::get<0>(LHC)) {
1008 const Attr *ThenAttr = std::get<1>(LHC);
1009 const Attr *ElseAttr = std::get<2>(LHC);
1011 diag::warn_attributes_likelihood_ifstmt_conflict)
1012 << ThenAttr << ThenAttr->getRange();
1014 << ElseAttr << ElseAttr->getRange();
1015 }
1016 }
1017
1018 if (ConstevalOrNegatedConsteval) {
1022 const auto *FD =
1024 if (FD && FD->isImmediateFunction())
1025 Immediate = true;
1026 }
1028 Diags.Report(IfLoc, diag::warn_consteval_if_always_true) << Immediate;
1029 }
1030
1031
1032
1033
1034
1035 if (isa(thenStmt)) {
1036 Diag(thenStmt->getBeginLoc(), diag::err_acc_update_as_body) << 0;
1038 }
1039
1040 return BuildIfStmt(IfLoc, StatementKind, LParenLoc, InitStmt, Cond, RParenLoc,
1041 thenStmt, ElseLoc, elseStmt);
1042}
1043
1049 Stmt *elseStmt) {
1052
1054 isa(Cond.get().second))
1056
1058 Cond.get().first, Cond.get().second, LParenLoc,
1059 RParenLoc, thenStmt, ElseLoc, elseStmt);
1060}
1061
1062namespace {
1063 struct CaseCompareFunctor {
1064 bool operator()(const std::pair<llvm::APSInt, CaseStmt*> &LHS,
1065 const llvm::APSInt &RHS) {
1066 return LHS.first < RHS;
1067 }
1068 bool operator()(const std::pair<llvm::APSInt, CaseStmt*> &LHS,
1069 const std::pair<llvm::APSInt, CaseStmt*> &RHS) {
1070 return LHS.first < RHS.first;
1071 }
1072 bool operator()(const llvm::APSInt &LHS,
1073 const std::pair<llvm::APSInt, CaseStmt*> &RHS) {
1074 return LHS < RHS.first;
1075 }
1076 };
1077}
1078
1079
1080
1081static bool CmpCaseVals(const std::pair<llvm::APSInt, CaseStmt*>& lhs,
1082 const std::pair<llvm::APSInt, CaseStmt*>& rhs) {
1083 if (lhs.first < rhs.first)
1084 return true;
1085
1086 if (lhs.first == rhs.first &&
1087 lhs.second->getCaseLoc() < rhs.second->getCaseLoc())
1088 return true;
1089 return false;
1090}
1091
1092
1093
1094static bool CmpEnumVals(const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,
1095 const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)
1096{
1097 return lhs.first < rhs.first;
1098}
1099
1100
1101
1102static bool EqEnumVals(const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,
1103 const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)
1104{
1105 return lhs.first == rhs.first;
1106}
1107
1108
1109
1111 if (const auto *FE = dyn_cast(E))
1112 E = FE->getSubExpr();
1113 while (const auto *ImpCast = dyn_cast(E)) {
1114 if (ImpCast->getCastKind() != CK_IntegralCast) break;
1115 E = ImpCast->getSubExpr();
1116 }
1118}
1119
1123
1124 public:
1125 SwitchConvertDiagnoser(Expr *Cond)
1127 Cond(Cond) {}
1128
1131 return S.Diag(Loc, diag::err_typecheck_statement_requires_integer) << T;
1132 }
1133
1136 return S.Diag(Loc, diag::err_switch_incomplete_class_type)
1138 }
1139
1142 return S.Diag(Loc, diag::err_switch_explicit_conversion) << T << ConvTy;
1143 }
1144
1147 return S.Diag(Conv->getLocation(), diag::note_switch_conversion)
1149 }
1150
1153 return S.Diag(Loc, diag::err_switch_multiple_conversions) << T;
1154 }
1155
1158 return S.Diag(Conv->getLocation(), diag::note_switch_conversion)
1160 }
1161
1164 llvm_unreachable("conversion functions are permitted");
1165 }
1166 } SwitchDiagnoser(Cond);
1167
1172
1173
1174
1175 Cond = CondResult.get();
1179
1180
1182}
1183
1188 Expr *CondExpr = Cond.get().second;
1189 assert((Cond.isInvalid() || CondExpr) && "switch with no condition");
1190
1192
1193
1194
1195
1199
1200
1201
1202 Diag(SwitchLoc, diag::warn_bool_switch_condition)
1204 }
1205 }
1206
1208
1210 LParenLoc, RParenLoc);
1213 return SS;
1214}
1215
1216static void AdjustAPSInt(llvm::APSInt &Val, unsigned BitWidth, bool IsSigned) {
1217 Val = Val.extOrTrunc(BitWidth);
1218 Val.setIsSigned(IsSigned);
1219}
1220
1221
1222
1224 unsigned UnpromotedWidth, bool UnpromotedSign) {
1225
1227 return;
1228
1229
1230
1231
1232 if (UnpromotedWidth < Val.getBitWidth()) {
1233 llvm::APSInt ConvVal(Val);
1234 AdjustAPSInt(ConvVal, UnpromotedWidth, UnpromotedSign);
1235 AdjustAPSInt(ConvVal, Val.getBitWidth(), Val.isSigned());
1236
1237
1238
1239 if (ConvVal != Val)
1240 S.Diag(Loc, diag::warn_case_value_overflow) << toString(Val, 10)
1242 }
1243}
1244
1246
1247
1248
1251 const Expr *CaseExpr,
1252 EnumValsTy::iterator &EI,
1253 EnumValsTy::iterator &EIEnd,
1254 const llvm::APSInt &Val) {
1256 return false;
1257
1260 if (const VarDecl *VD = dyn_cast(DRE->getDecl())) {
1261 QualType VarType = VD->getType();
1265 return false;
1266 }
1267 }
1268
1269 if (ED->hasAttr())
1271
1272 while (EI != EIEnd && EI->first < Val)
1273 EI++;
1274
1275 if (EI != EIEnd && EI->first == Val)
1276 return false;
1277
1278 return true;
1279}
1280
1282 const Expr *Case) {
1285
1288 if (!CondEnumType || !CaseEnumType)
1289 return;
1290
1291
1294 return;
1295 if (!CaseEnumType->getDecl()->getIdentifier() &&
1296 !CaseEnumType->getDecl()->getTypedefNameForAnonDecl())
1297 return;
1298
1300 return;
1301
1302 S.Diag(Case->getExprLoc(), diag::warn_comparison_of_mixed_enum_types_switch)
1305}
1306
1309 Stmt *BodyStmt) {
1312 assert(SS == getCurFunction()->SwitchStack.back().getPointer() &&
1313 "switch stack missing push/pop!");
1314
1316
1317 if (!BodyStmt) return StmtError();
1318
1319
1320
1321
1322
1323 if (isa(BodyStmt)) {
1324 Diag(BodyStmt->getBeginLoc(), diag::err_acc_update_as_body) << 3;
1326 }
1327
1328 SS->setBody(BodyStmt, SwitchLoc);
1329
1331 if (!CondExpr) return StmtError();
1332
1334
1335
1336
1337
1338
1339
1340
1341
1342 const Expr *CondExprBeforePromotion = CondExpr;
1343 QualType CondTypeBeforePromotion =
1345
1346
1347
1348 bool HasDependentValue
1350 unsigned CondWidth = HasDependentValue ? 0 : Context.getIntWidth(CondType);
1352
1353
1354
1355
1356
1357 unsigned CondWidthBeforePromotion
1358 = HasDependentValue ? 0 : Context.getIntWidth(CondTypeBeforePromotion);
1359 bool CondIsSignedBeforePromotion
1361
1362
1363
1364
1366 CaseValsTy CaseVals;
1367
1368
1369 typedef std::vector<std::pair<llvm::APSInt, CaseStmt*> > CaseRangesTy;
1370 CaseRangesTy CaseRanges;
1371
1373
1374 bool CaseListIsErroneous = false;
1375
1376
1377
1378
1381
1382 if (DefaultStmt *DS = dyn_cast(SC)) {
1383 if (TheDefaultStmt) {
1384 Diag(DS->getDefaultLoc(), diag::err_multiple_default_labels_defined);
1385 Diag(TheDefaultStmt->getDefaultLoc(), diag::note_duplicate_case_prev);
1386
1387
1388
1389
1390
1391 CaseListIsErroneous = true;
1392 }
1393 TheDefaultStmt = DS;
1394
1395 } else {
1396 CaseStmt *CS = cast(SC);
1397
1399
1401 HasDependentValue = true;
1402 break;
1403 }
1404
1405
1406
1407 const Expr *LoBeforePromotion = Lo;
1410
1411
1412
1414 CondIsSignedBeforePromotion);
1415
1416
1418 LoBeforePromotion);
1419
1420
1421 AdjustAPSInt(LoVal, CondWidth, CondIsSigned);
1422
1423
1426 HasDependentValue = true;
1427 break;
1428 }
1429 CaseRanges.push_back(std::make_pair(LoVal, CS));
1430 } else
1431 CaseVals.push_back(std::make_pair(LoVal, CS));
1432 }
1433 }
1434
1435 if (!HasDependentValue) {
1436
1437
1438 llvm::APSInt ConstantCondValue;
1439 bool HasConstantCond = false;
1440 if (!TheDefaultStmt) {
1444 if (Result.Val.isInt())
1445 ConstantCondValue = Result.Val.getInt();
1446 assert(!HasConstantCond ||
1447 (ConstantCondValue.getBitWidth() == CondWidth &&
1448 ConstantCondValue.isSigned() == CondIsSigned));
1449 Diag(SwitchLoc, diag::warn_switch_default);
1450 }
1451 bool ShouldCheckConstantCond = HasConstantCond;
1452
1453
1454 llvm::stable_sort(CaseVals, CmpCaseVals);
1455
1456 if (!CaseVals.empty()) {
1457 for (unsigned i = 0, e = CaseVals.size(); i != e; ++i) {
1458 if (ShouldCheckConstantCond &&
1459 CaseVals[i].first == ConstantCondValue)
1460 ShouldCheckConstantCond = false;
1461
1462 if (i != 0 && CaseVals[i].first == CaseVals[i-1].first) {
1463
1464
1465 StringRef PrevString, CurrString;
1468 if (DeclRefExpr *DeclRef = dyn_cast(PrevCase)) {
1469 PrevString = DeclRef->getDecl()->getName();
1470 }
1471 if (DeclRefExpr *DeclRef = dyn_cast(CurrCase)) {
1472 CurrString = DeclRef->getDecl()->getName();
1473 }
1475 CaseVals[i-1].first.toString(CaseValStr);
1476
1477 if (PrevString == CurrString)
1478 Diag(CaseVals[i].second->getLHS()->getBeginLoc(),
1479 diag::err_duplicate_case)
1480 << (PrevString.empty() ? CaseValStr.str() : PrevString);
1481 else
1482 Diag(CaseVals[i].second->getLHS()->getBeginLoc(),
1483 diag::err_duplicate_case_differing_expr)
1484 << (PrevString.empty() ? CaseValStr.str() : PrevString)
1485 << (CurrString.empty() ? CaseValStr.str() : CurrString)
1486 << CaseValStr;
1487
1488 Diag(CaseVals[i - 1].second->getLHS()->getBeginLoc(),
1489 diag::note_duplicate_case_prev);
1490
1491
1492 CaseListIsErroneous = true;
1493 }
1494 }
1495 }
1496
1497
1498
1499 if (!CaseRanges.empty()) {
1500
1501
1502 llvm::stable_sort(CaseRanges);
1503
1504
1505 std::vectorllvm::APSInt HiVals;
1506 for (unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {
1507 llvm::APSInt &LoVal = CaseRanges[i].first;
1508 CaseStmt *CR = CaseRanges[i].second;
1510
1511 const Expr *HiBeforePromotion = Hi;
1514
1515
1516
1518 CondWidthBeforePromotion, CondIsSignedBeforePromotion);
1519
1520
1521 AdjustAPSInt(HiVal, CondWidth, CondIsSigned);
1522
1523
1524 if (LoVal > HiVal) {
1527 CaseRanges.erase(CaseRanges.begin()+i);
1528 --i;
1529 --e;
1530 continue;
1531 }
1532
1533 if (ShouldCheckConstantCond &&
1534 LoVal <= ConstantCondValue &&
1535 ConstantCondValue <= HiVal)
1536 ShouldCheckConstantCond = false;
1537
1538 HiVals.push_back(HiVal);
1539 }
1540
1541
1542
1543
1544 for (unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {
1545 llvm::APSInt &CRLo = CaseRanges[i].first;
1546 llvm::APSInt &CRHi = HiVals[i];
1547 CaseStmt *CR = CaseRanges[i].second;
1548
1549
1550
1551 CaseStmt *OverlapStmt = nullptr;
1552 llvm::APSInt OverlapVal(32);
1553
1554
1555
1556 CaseValsTy::iterator I =
1557 llvm::lower_bound(CaseVals, CRLo, CaseCompareFunctor());
1558 if (I != CaseVals.end() && I->first < CRHi) {
1559 OverlapVal = I->first;
1560 OverlapStmt = I->second;
1561 }
1562
1563
1564 I = std::upper_bound(I, CaseVals.end(), CRHi, CaseCompareFunctor());
1565 if (I != CaseVals.begin() && (I-1)->first >= CRLo) {
1566 OverlapVal = (I-1)->first;
1567 OverlapStmt = (I-1)->second;
1568 }
1569
1570
1571
1572 if (i && CRLo <= HiVals[i-1]) {
1573 OverlapVal = HiVals[i-1];
1574 OverlapStmt = CaseRanges[i-1].second;
1575 }
1576
1577 if (OverlapStmt) {
1578
1580 << toString(OverlapVal, 10);
1582 diag::note_duplicate_case_prev);
1583
1584
1585 CaseListIsErroneous = true;
1586 }
1587 }
1588 }
1589
1590
1591 if (!CaseListIsErroneous && !CaseListIsIncomplete &&
1592 ShouldCheckConstantCond) {
1593
1594
1595 Diag(CondExpr->getExprLoc(), diag::warn_missing_case_for_condition)
1596 << toString(ConstantCondValue, 10)
1598 }
1599
1600
1601
1602
1603
1604
1606
1607
1608 if (!CaseListIsErroneous && !CaseListIsIncomplete && !HasConstantCond &&
1613
1614
1615
1617 llvm::APSInt Val = EDI->getInitVal();
1619 EnumVals.push_back(std::make_pair(Val, EDI));
1620 }
1621 llvm::stable_sort(EnumVals, CmpEnumVals);
1622 auto EI = EnumVals.begin(), EIEnd =
1623 std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals);
1624
1625
1626 for (CaseValsTy::const_iterator CI = CaseVals.begin();
1627 CI != CaseVals.end(); CI++) {
1628 Expr *CaseExpr = CI->second->getLHS();
1630 CI->first))
1631 Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
1632 << CondTypeBeforePromotion;
1633 }
1634
1635
1636 EI = EnumVals.begin();
1637 for (CaseRangesTy::const_iterator RI = CaseRanges.begin();
1638 RI != CaseRanges.end(); RI++) {
1639 Expr *CaseExpr = RI->second->getLHS();
1641 RI->first))
1642 Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
1643 << CondTypeBeforePromotion;
1644
1645 llvm::APSInt Hi =
1646 RI->second->getRHS()->EvaluateKnownConstInt(Context);
1648
1649 CaseExpr = RI->second->getRHS();
1651 Hi))
1652 Diag(CaseExpr->getExprLoc(), diag::warn_not_in_enum)
1653 << CondTypeBeforePromotion;
1654 }
1655
1656
1657 auto CI = CaseVals.begin();
1658 auto RI = CaseRanges.begin();
1659 bool hasCasesNotInSwitch = false;
1660
1662
1663 for (EI = EnumVals.begin(); EI != EIEnd; EI++) {
1664
1665 switch (EI->second->getAvailability()) {
1667
1669 continue;
1670
1672
1673
1675 break;
1676 }
1677
1678 if (EI->second->hasAttr())
1679 continue;
1680
1681
1682 while (CI != CaseVals.end() && CI->first < EI->first)
1683 CI++;
1684
1685 if (CI != CaseVals.end() && CI->first == EI->first)
1686 continue;
1687
1688
1689 for (; RI != CaseRanges.end(); RI++) {
1690 llvm::APSInt Hi =
1691 RI->second->getRHS()->EvaluateKnownConstInt(Context);
1693 if (EI->first <= Hi)
1694 break;
1695 }
1696
1697 if (RI == CaseRanges.end() || EI->first < RI->first) {
1698 hasCasesNotInSwitch = true;
1699 UnhandledNames.push_back(EI->second->getDeclName());
1700 }
1701 }
1702
1703 if (TheDefaultStmt && UnhandledNames.empty() && ED->isClosedNonFlag())
1704 Diag(TheDefaultStmt->getDefaultLoc(), diag::warn_unreachable_default);
1705
1706
1707 if (!UnhandledNames.empty()) {
1708 auto DB = Diag(CondExpr->getExprLoc(), TheDefaultStmt
1709 ? diag::warn_def_missing_case
1710 : diag::warn_missing_case)
1712
1713 for (size_t I = 0, E = std::min(UnhandledNames.size(), (size_t)3);
1714 I != E; ++I)
1715 DB << UnhandledNames[I];
1716 }
1717
1718 if (!hasCasesNotInSwitch)
1720 }
1721 }
1722
1723 if (BodyStmt)
1725 diag::warn_empty_switch_body);
1726
1727
1728
1729 if (CaseListIsErroneous)
1731
1732 return SS;
1733}
1734
1735void
1737 Expr *SrcExpr) {
1739 return;
1740
1746
1749
1751 AdjustAPSInt(RhsVal, DstWidth, DstIsSigned);
1752 const EnumDecl *ED = ET->getDecl();
1753
1755 return;
1756
1757 if (ED->hasAttr()) {
1759 Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)
1761 } else {
1765
1766
1767
1769 llvm::APSInt Val = EDI->getInitVal();
1771 EnumVals.push_back(std::make_pair(Val, EDI));
1772 }
1773 if (EnumVals.empty())
1774 return;
1775 llvm::stable_sort(EnumVals, CmpEnumVals);
1776 EnumValsTy::iterator EIend =
1777 std::unique(EnumVals.begin(), EnumVals.end(), EqEnumVals);
1778
1779
1780 EnumValsTy::const_iterator EI = EnumVals.begin();
1781 while (EI != EIend && EI->first < RhsVal)
1782 EI++;
1783 if (EI == EIend || EI->first != RhsVal) {
1784 Diag(SrcExpr->getExprLoc(), diag::warn_not_in_enum_assignment)
1786 }
1787 }
1788 }
1789 }
1790}
1791
1797
1798 auto CondVal = Cond.get();
1799 CheckBreakContinueBinding(CondVal.second);
1800
1801 if (CondVal.second &&
1802 .isIgnored(diag::warn_comma_operator, CondVal.second->getExprLoc()))
1803 CommaVisitor(*this).Visit(CondVal.second);
1804
1805
1806
1807
1808
1809 if (isa(Body)) {
1810 Diag(Body->getBeginLoc(), diag::err_acc_update_as_body) << 1;
1812 }
1813
1814 if (isa(Body))
1816
1818 WhileLoc, LParenLoc, RParenLoc);
1819}
1820
1825 assert(Cond && "ActOnDoStmt(): missing expression");
1826
1827 CheckBreakContinueBinding(Cond);
1831 Cond = CondResult.get();
1832
1833 CondResult = ActOnFinishFullExpr(Cond, DoLoc, false);
1836 Cond = CondResult.get();
1837
1838
1841 CommaVisitor(*this).Visit(Cond);
1842
1843
1844
1845
1846
1847 if (isa(Body)) {
1848 Diag(Body->getBeginLoc(), diag::err_acc_update_as_body) << 2;
1850 }
1851
1852 return new (Context) DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen);
1853}
1854
1855namespace {
1856
1858
1859
1860
1861
1863 DeclSetVector &Decls;
1865 bool Simple;
1866 public:
1868
1869 DeclExtractor(Sema &S, DeclSetVector &Decls,
1871 Inherited(S.Context),
1872 Decls(Decls),
1873 Ranges(Ranges),
1874 Simple(true) {}
1875
1876 bool isSimple() { return Simple; }
1877
1878
1880 Simple = false;
1881 }
1882
1883
1884
1885 void VisitStmt(Stmt *S) { Simple = false; }
1886
1888 Visit(E->getLHS());
1889 Visit(E->getRHS());
1890 }
1891
1892 void VisitCastExpr(CastExpr *E) {
1893 Visit(E->getSubExpr());
1894 }
1895
1897
1898 if (E->getOpcode() == UO_Deref)
1899 Simple = false;
1900 else
1901 Visit(E->getSubExpr());
1902 }
1903
1905 Visit(E->getCond());
1906 Visit(E->getTrueExpr());
1907 Visit(E->getFalseExpr());
1908 }
1909
1911 Visit(E->getSubExpr());
1912 }
1913
1915 Visit(E->getOpaqueValue()->getSourceExpr());
1916 Visit(E->getFalseExpr());
1917 }
1918
1925
1927 VarDecl *VD = dyn_cast(E->getDecl());
1928 if (!VD) {
1929
1930 Simple = false;
1931 return;
1932 }
1933
1935
1936 Decls.insert(VD);
1937 }
1938
1939 };
1940
1941
1942
1944 DeclSetVector &Decls;
1945 bool FoundDecl;
1946
1947 public:
1949
1950 DeclMatcher(Sema &S, DeclSetVector &Decls, Stmt *Statement) :
1951 Inherited(S.Context), Decls(Decls), FoundDecl(false) {
1952 if (!Statement) return;
1953
1954 Visit(Statement);
1955 }
1956
1957 void VisitReturnStmt(ReturnStmt *S) {
1958 FoundDecl = true;
1959 }
1960
1961 void VisitBreakStmt(BreakStmt *S) {
1962 FoundDecl = true;
1963 }
1964
1965 void VisitGotoStmt(GotoStmt *S) {
1966 FoundDecl = true;
1967 }
1968
1969 void VisitCastExpr(CastExpr *E) {
1970 if (E->getCastKind() == CK_LValueToRValue)
1971 CheckLValueToRValueCast(E->getSubExpr());
1972 else
1973 Visit(E->getSubExpr());
1974 }
1975
1976 void CheckLValueToRValueCast(Expr *E) {
1978
1979 if (isa(E)) {
1980 return;
1981 }
1982
1984 Visit(CO->getCond());
1985 CheckLValueToRValueCast(CO->getTrueExpr());
1986 CheckLValueToRValueCast(CO->getFalseExpr());
1987 return;
1988 }
1989
1991 dyn_cast(E)) {
1992 CheckLValueToRValueCast(BCO->getOpaqueValue()->getSourceExpr());
1993 CheckLValueToRValueCast(BCO->getFalseExpr());
1994 return;
1995 }
1996
1997 Visit(E);
1998 }
1999
2001 if (VarDecl *VD = dyn_cast(E->getDecl()))
2002 if (Decls.count(VD))
2003 FoundDecl = true;
2004 }
2005
2007
2008
2009 for (auto *S : POE->semantics()) {
2010 if (auto *OVE = dyn_cast(S))
2011
2012 Visit(OVE->getSourceExpr());
2013 else
2014 Visit(S);
2015 }
2016 }
2017
2018 bool FoundDeclInUse() { return FoundDecl; }
2019
2020 };
2021
2022 void CheckForLoopConditionalStatement(Sema &S, Expr *Second,
2024
2025 if (!Second) return;
2026
2027 if (S.Diags.isIgnored(diag::warn_variables_not_in_loop_body,
2029 return;
2030
2032 DeclSetVector Decls;
2034 DeclExtractor DE(S, Decls, Ranges);
2035 DE.Visit(Second);
2036
2037
2038 if (!DE.isSimple()) return;
2039
2040
2041 if (Decls.size() == 0) return;
2042
2043
2044 for (auto *VD : Decls)
2046 return;
2047
2048 if (DeclMatcher(S, Decls, Second).FoundDeclInUse() ||
2049 DeclMatcher(S, Decls, Third).FoundDeclInUse() ||
2050 DeclMatcher(S, Decls, Body).FoundDeclInUse())
2051 return;
2052
2053
2054 if (Decls.size() > 4) {
2055 PDiag << 0;
2056 } else {
2057 PDiag << (unsigned)Decls.size();
2058 for (auto *VD : Decls)
2060 }
2061
2062 for (auto Range : Ranges)
2064
2065 S.Diag(Ranges.begin()->getBegin(), PDiag);
2066 }
2067
2068
2069
2070 bool ProcessIterationStmt(Sema &S, Stmt* Statement, bool &Increment,
2072 if (auto Cleanups = dyn_cast(Statement))
2073 if (!Cleanups->cleanupsHaveSideEffects())
2074 Statement = Cleanups->getSubExpr();
2075
2076 if (UnaryOperator *UO = dyn_cast(Statement)) {
2077 switch (UO->getOpcode()) {
2078 default: return false;
2079 case UO_PostInc:
2080 case UO_PreInc:
2081 Increment = true;
2082 break;
2083 case UO_PostDec:
2084 case UO_PreDec:
2085 Increment = false;
2086 break;
2087 }
2088 DRE = dyn_cast(UO->getSubExpr());
2089 return DRE;
2090 }
2091
2096 default: return false;
2097 case OO_PlusPlus:
2098 Increment = true;
2099 break;
2100 case OO_MinusMinus:
2101 Increment = false;
2102 break;
2103 }
2104 DRE = dyn_cast(Call->getArg(0));
2105 return DRE;
2106 }
2107
2108 return false;
2109 }
2110
2111
2112
2116 bool InSwitch = false;
2117
2118 public:
2119 BreakContinueFinder(Sema &S, const Stmt* Body) :
2120 Inherited(S.Context) {
2121 Visit(Body);
2122 }
2123
2125
2127 ContinueLoc = E->getContinueLoc();
2128 }
2129
2130 void VisitBreakStmt(const BreakStmt* E) {
2131 if (!InSwitch)
2132 BreakLoc = E->getBreakLoc();
2133 }
2134
2135 void VisitSwitchStmt(const SwitchStmt* S) {
2136 if (const Stmt *Init = S->getInit())
2137 Visit(Init);
2138 if (const Stmt *CondVar = S->getConditionVariableDeclStmt())
2139 Visit(CondVar);
2140 if (const Stmt *Cond = S->getCond())
2141 Visit(Cond);
2142
2143
2144 InSwitch = true;
2145 if (const Stmt *Body = S->getBody())
2146 Visit(Body);
2147 InSwitch = false;
2148 }
2149
2150 void VisitForStmt(const ForStmt *S) {
2151
2152
2153 if (const Stmt *Init = S->getInit())
2154 Visit(Init);
2155 }
2156
2157 void VisitWhileStmt(const WhileStmt *) {
2158
2159
2160 }
2161
2162 void VisitDoStmt(const DoStmt *) {
2163
2164
2165 }
2166
2168
2169
2170 if (const Stmt *Init = S->getInit())
2171 Visit(Init);
2172 if (const Stmt *Range = S->getRangeStmt())
2174 if (const Stmt *Begin = S->getBeginStmt())
2176 if (const Stmt *End = S->getEndStmt())
2177 Visit(End);
2178 }
2179
2181
2182
2183 if (const Stmt *Element = S->getElement())
2184 Visit(Element);
2185 if (const Stmt *Collection = S->getCollection())
2186 Visit(Collection);
2187 }
2188
2189 bool ContinueFound() { return ContinueLoc.isValid(); }
2190 bool BreakFound() { return BreakLoc.isValid(); }
2191 SourceLocation GetContinueLoc() { return ContinueLoc; }
2193
2194 };
2195
2196
2197
2198
2199
2200
2201 void CheckForRedundantIteration(Sema &S, Expr *Third, Stmt *Body) {
2202
2203 if (!Body || !Third) return;
2204
2205 if (S.Diags.isIgnored(diag::warn_redundant_loop_iteration,
2207 return;
2208
2209
2210 CompoundStmt *CS = dyn_cast(Body);
2211 if (!CS || CS->body_empty()) return;
2213 if (!LastStmt) return;
2214
2215 bool LoopIncrement, LastIncrement;
2217
2218 if (!ProcessIterationStmt(S, Third, LoopIncrement, LoopDRE)) return;
2219 if (!ProcessIterationStmt(S, LastStmt, LastIncrement, LastDRE)) return;
2220
2221
2222
2223 if (LoopIncrement != LastIncrement ||
2225
2226 if (BreakContinueFinder(S, Body).ContinueFound()) return;
2227
2228 S.Diag(LastDRE->getLocation(), diag::warn_redundant_loop_iteration)
2229 << LastDRE->getDecl() << LastIncrement;
2230 S.Diag(LoopDRE->getLocation(), diag::note_loop_iteration_here)
2231 << LoopIncrement;
2232 }
2233
2234}
2235
2236
2237void Sema::CheckBreakContinueBinding(Expr *E) {
2239 return;
2240 BreakContinueFinder BCFinder(*this, E);
2242 if (BCFinder.BreakFound() && BreakParent) {
2244 Diag(BCFinder.GetBreakLoc(), diag::warn_break_binds_to_switch);
2245 } else {
2246 Diag(BCFinder.GetBreakLoc(), diag::warn_loop_ctrl_binds_to_inner)
2247 << "break";
2248 }
2249 } else if (BCFinder.ContinueFound() && CurScope->getContinueParent()) {
2250 Diag(BCFinder.GetContinueLoc(), diag::warn_loop_ctrl_binds_to_inner)
2251 << "continue";
2252 }
2253}
2254
2258 Stmt *Body) {
2261
2263 if (DeclStmt *DS = dyn_cast_or_null(First)) {
2264
2265
2266
2267 const Decl *NonVarSeen = nullptr;
2268 bool VarDeclSeen = false;
2269 for (auto *DI : DS->decls()) {
2270 if (VarDecl *VD = dyn_cast(DI)) {
2271 VarDeclSeen = true;
2273 Diag(DI->getLocation(), diag::err_non_local_variable_decl_in_for);
2274 DI->setInvalidDecl();
2275 }
2276 } else if (!NonVarSeen) {
2277
2278
2279
2280
2281 NonVarSeen = DI;
2282 }
2283 }
2284
2285
2286 if (NonVarSeen && !VarDeclSeen)
2287 Diag(NonVarSeen->getLocation(), diag::err_non_variable_decl_in_for);
2288 }
2289 }
2290
2291 CheckBreakContinueBinding(Second.get().second);
2292 CheckBreakContinueBinding(third.get());
2293
2294 if (!Second.get().first)
2295 CheckForLoopConditionalStatement(*this, Second.get().second, third.get(),
2296 Body);
2297 CheckForRedundantIteration(*this, third.get(), Body);
2298
2299 if (Second.get().second &&
2301 Second.get().second->getExprLoc()))
2302 CommaVisitor(*this).Visit(Second.get().second);
2303
2305 if (isa(Body))
2307
2310 Body, ForLoc, LParenLoc, RParenLoc);
2311}
2312
2314
2315
2319
2324}
2325
2326
2327
2330 if (Decl->getType()->isUndeducedType()) {
2334 return true;
2335 }
2337 }
2338
2339
2340
2342 if (!isa(Init) && Init->getType()->isVoidType()) {
2343 SemaRef.Diag(Loc, DiagID) << Init->getType();
2344 } else {
2347 Decl->getTypeSourceInfo()->getTypeLoc(), Init, InitType, Info);
2350 SemaRef.Diag(Loc, DiagID) << Init->getType();
2351 }
2352
2353 if (InitType.isNull()) {
2355 return true;
2356 }
2357 Decl->setType(InitType);
2358
2359
2360
2361
2362 if (SemaRef.getLangOpts().ObjCAutoRefCount &&
2365
2369 return false;
2370}
2371
2372namespace {
2373
2374
2375enum BeginEndFunction {
2376 BEF_begin,
2377 BEF_end
2378};
2379
2380
2381
2382
2383
2384void NoteForRangeBeginEndFunction(Sema &SemaRef, Expr *E,
2385 BeginEndFunction BEF) {
2386 CallExpr *CE = dyn_cast(E);
2387 if (!CE)
2388 return;
2390 if ()
2391 return;
2393
2394 std::string Description;
2395 bool IsTemplate = false;
2398 FunTmpl->getTemplateParameters(), *D->getTemplateSpecializationArgs());
2399 IsTemplate = true;
2400 }
2401
2402 SemaRef.Diag(Loc, diag::note_for_range_begin_end)
2403 << BEF << IsTemplate << Description << E->getType();
2404}
2405
2406
2415 return Decl;
2416}
2417
2418}
2419
2423}
2424
2430
2433
2435
2436 if (InitStmt)
2437 return Diag(InitStmt->getBeginLoc(), diag::err_objc_for_range_init_stmt)
2440 }
2441
2443 assert(DS && "first part of for range not a decl stmt");
2444
2446 Diag(DS->getBeginLoc(), diag::err_type_defined_in_for_range);
2448 }
2449
2450
2451
2457 }
2458
2459
2460
2465 }
2466 }
2467
2468
2469
2470 const auto DepthStr = std::to_string(S->getDepth() / 2);
2472 VarDecl *RangeVar = BuildForRangeVarDecl(*this, RangeLoc,
2474 std::string("__range") + DepthStr);
2476 diag::err_for_range_deduction_failure)) {
2479 }
2480
2481
2488 }
2489
2491 ForLoc, CoawaitLoc, InitStmt, ColonLoc, RangeDecl.get(),
2492 nullptr, nullptr,
2493 nullptr, nullptr, DS, RParenLoc, Kind,
2494 LifetimeExtendTemps);
2498 }
2499
2500 return R;
2501}
2502
2503
2504
2505
2506
2507
2508
2509
2510
2511
2517 ExprResult *EndExpr, BeginEndFunction *BEF) {
2521 ColonLoc);
2522
2523 LookupResult BeginMemberLookup(SemaRef, BeginNameInfo,
2526
2527 auto BuildBegin = [&] {
2528 *BEF = BEF_begin;
2531 BeginMemberLookup, CandidateSet,
2532 BeginRange, BeginExpr);
2533
2536 SemaRef.Diag(BeginRange->getBeginLoc(), diag::note_in_for_range)
2537 << ColonLoc << BEF_begin << BeginRange->getType();
2538 return RangeStatus;
2539 }
2541
2542
2543
2545 BeginExpr->get());
2548 }
2550 diag::err_for_range_iter_deduction_failure)) {
2551 NoteForRangeBeginEndFunction(SemaRef, BeginExpr->get(), *BEF);
2553 }
2555 };
2556
2557 auto BuildEnd = [&] {
2558 *BEF = BEF_end;
2561 EndMemberLookup, CandidateSet,
2562 EndRange, EndExpr);
2565 SemaRef.Diag(EndRange->getBeginLoc(), diag::note_in_for_range)
2566 << ColonLoc << BEF_end << EndRange->getType();
2567 return RangeStatus;
2568 }
2570 diag::err_for_range_iter_deduction_failure)) {
2571 NoteForRangeBeginEndFunction(SemaRef, EndExpr->get(), *BEF);
2573 }
2575 };
2576
2578
2579
2580
2581
2582
2586
2590
2591 if (BeginMemberLookup.empty() != EndMemberLookup.empty()) {
2592
2593
2594
2595
2596 auto BuildNonmember = [&](
2602
2605
2606 switch (BuildFound()) {
2609
2613 SemaRef.PDiag(diag::err_for_range_invalid)
2614 << BeginRange->getType() << BEFFound),
2616 [[fallthrough]];
2617
2621 diag::note_for_range_member_begin_end_ignored)
2622 << BeginRange->getType() << BEFFound;
2623 }
2625 }
2626 llvm_unreachable("unexpected ForRangeStatus");
2627 };
2628 if (BeginMemberLookup.empty())
2629 return BuildNonmember(BEF_end, EndMemberLookup, BuildEnd, BuildBegin);
2630 return BuildNonmember(BEF_begin, BeginMemberLookup, BuildBegin, BuildEnd);
2631 }
2632 } else {
2633
2634
2635
2636
2637 }
2638
2641 return BuildEnd();
2642}
2643
2644
2645
2646
2650 Stmt *InitStmt,
2651 Stmt *LoopVarDecl,
2656
2657
2659 {
2661
2662 AdjustedRange = SemaRef.BuildUnaryOp(S, RangeLoc, UO_Deref, Range);
2665
2667 S, ForLoc, CoawaitLoc, InitStmt, LoopVarDecl, ColonLoc,
2671 }
2672
2673
2674
2675
2676 SemaRef.Diag(RangeLoc, diag::err_for_range_dereference)
2679 S, ForLoc, CoawaitLoc, InitStmt, LoopVarDecl, ColonLoc,
2681}
2682
2689
2690
2691
2692
2693
2694
2695
2696
2697
2699
2700 DeclStmt *RangeDS = cast(RangeDecl);
2703
2704 DeclStmt *LoopVarDS = cast(LoopVarDecl);
2706
2709 ExprResult NotEqExpr = Cond, IncrExpr = Inc;
2710
2712
2714
2715
2716
2718 if (auto *DD = dyn_cast(LoopVar))
2719 for (auto *Binding : DD->bindings())
2722 }
2723 } else if (!BeginDeclStmt.get()) {
2725
2727
2732
2737
2743
2745 diag::err_for_range_incomplete_type))
2747
2748
2752 for (auto *MTE : LifetimeExtendTemps)
2754 }
2755
2756
2757
2758 const auto DepthStr = std::to_string(S->getDepth() / 2);
2759 VarDecl *BeginVar = BuildForRangeVarDecl(*this, ColonLoc, AutoType,
2760 std::string("__begin") + DepthStr);
2761 VarDecl *EndVar = BuildForRangeVarDecl(*this, ColonLoc, AutoType,
2762 std::string("__end") + DepthStr);
2763
2764
2767
2768
2769
2770
2771
2772
2773 BeginExpr = BeginRangeRef;
2778 }
2780 diag::err_for_range_iter_deduction_failure)) {
2781 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);
2783 }
2784
2785
2787 if (const ConstantArrayType *CAT = dyn_cast(UnqAT))
2791 dyn_cast(UnqAT)) {
2792
2793
2794
2795
2796
2797
2798
2799
2800
2801
2802
2803
2804
2805
2806
2807
2808
2809
2810
2811
2812
2813
2816 true,
2818 VAT->desugar(), RangeLoc))
2823
2826 true,
2829 VAT->getElementType(), RangeLoc))
2832 if (SizeOfEachElementExprR.isInvalid())
2834
2835 BoundExpr =
2837 SizeOfVLAExprR.get(), SizeOfEachElementExprR.get());
2840
2841 } else {
2842
2843
2844 llvm_unreachable("Unexpected array type in for-range");
2845 }
2846
2847
2848 EndExpr = ActOnBinOp(S, ColonLoc, tok::plus, EndRangeRef.get(),
2849 BoundExpr.get());
2853 diag::err_for_range_iter_deduction_failure)) {
2854 NoteForRangeBeginEndFunction(*this, EndExpr.get(), BEF_end);
2856 }
2857 } else {
2860 BeginEndFunction BEFFailure;
2862 *this, BeginRangeRef.get(), EndRangeRef.get(), RangeType, BeginVar,
2863 EndVar, ColonLoc, CoawaitLoc, &CandidateSet, &BeginExpr, &EndExpr,
2864 &BEFFailure);
2865
2867 BEFFailure == BEF_begin) {
2868
2869
2872 QualType ArrayTy = PVD->getOriginalType();
2873 QualType PointerTy = PVD->getType();
2875 Diag(Range->getBeginLoc(), diag::err_range_on_array_parameter)
2876 << RangeLoc << PVD << ArrayTy << PointerTy;
2877 Diag(PVD->getLocation(), diag::note_declared_at);
2879 }
2880 }
2881 }
2882
2883
2884
2886 CoawaitLoc, InitStmt,
2887 LoopVarDecl, ColonLoc,
2888 Range, RangeLoc,
2889 RParenLoc);
2891 return SR;
2892 }
2893
2894
2896 Expr *Range = BEFFailure ? EndRangeRef.get() : BeginRangeRef.get();
2899 PDiag(diag::err_for_range_invalid)
2900 << RangeLoc << Range->getType()
2901 << BEFFailure),
2903 }
2904
2907 }
2908
2910 "invalid range expression in for loop");
2911
2912
2913
2917 ? diag::warn_for_range_begin_end_types_differ
2918 : diag::ext_for_range_begin_end_types_differ)
2919 << BeginType << EndType;
2920 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);
2921 NoteForRangeBeginEndFunction(*this, EndExpr.get(), BEF_end);
2922 }
2923
2924 BeginDeclStmt =
2926 EndDeclStmt =
2928
2934
2939
2940
2941 NotEqExpr = ActOnBinOp(S, ColonLoc, tok::exclaimequal,
2942 BeginRef.get(), EndRef.get());
2946 NotEqExpr =
2949 Diag(RangeLoc, diag::note_for_range_invalid_iterator)
2950 << RangeLoc << 0 << BeginRangeRef.get()->getType();
2951 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);
2953 NoteForRangeBeginEndFunction(*this, EndExpr.get(), BEF_end);
2955 }
2956
2957
2962
2963 IncrExpr = ActOnUnaryOp(S, ColonLoc, tok::plusplus, BeginRef.get());
2964 if (!IncrExpr.isInvalid() && CoawaitLoc.isValid())
2965
2966
2967
2969 if (!IncrExpr.isInvalid())
2970 IncrExpr = ActOnFinishFullExpr(IncrExpr.get(), false);
2971 if (IncrExpr.isInvalid()) {
2972 Diag(RangeLoc, diag::note_for_range_invalid_iterator)
2973 << RangeLoc << 2 << BeginRangeRef.get()->getType() ;
2974 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);
2976 }
2977
2978
2983
2986 Diag(RangeLoc, diag::note_for_range_invalid_iterator)
2987 << RangeLoc << 1 << BeginRangeRef.get()->getType();
2988 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);
2990 }
2991
2992
2993
2998 NoteForRangeBeginEndFunction(*this, BeginExpr.get(), BEF_begin);
2999 }
3000 }
3001
3002
3003
3006
3007
3008
3011
3013 InitStmt, RangeDS, cast_or_null(BeginDeclStmt.get()),
3014 cast_or_null(EndDeclStmt.get()), NotEqExpr.get(),
3015 IncrExpr.get(), LoopVarDS, nullptr, ForLoc, CoawaitLoc,
3016 ColonLoc, RParenLoc);
3017}
3018
3019
3020
3021
3022
3023
3024
3025
3030 if (!InitExpr)
3031 return;
3032
3034
3035 if (auto Cleanups = dyn_cast(InitExpr))
3036 if (!Cleanups->cleanupsHaveSideEffects())
3037 InitExpr = Cleanups->getSubExpr();
3038
3040 dyn_cast(InitExpr);
3041
3042
3043 if (!MTE)
3044 return;
3045
3047
3048
3049
3050 while (!isa(E) && !isa(E)) {
3051 if (const CXXConstructExpr *CCE = dyn_cast(E)) {
3052 E = CCE->getArg(0);
3054 const MemberExpr *ME = cast(Call->getCallee());
3056 } else {
3059 }
3061 }
3062
3063 QualType ReferenceReturnType;
3064 if (isa(E)) {
3066 } else {
3071 ReferenceReturnType = ReturnType;
3072 }
3073
3074 if (!ReferenceReturnType.isNull()) {
3075
3076
3077
3079 diag::warn_for_range_const_ref_binds_temp_built_from_ref)
3080 << VD << VariableType << ReferenceReturnType;
3085 SemaRef.Diag(VD->getBeginLoc(), diag::note_use_type_or_non_reference)
3086 << NonReferenceType << NewReferenceType << VD->getSourceRange()
3089
3090
3091
3092
3093 SemaRef.Diag(VD->getLocation(), diag::warn_for_range_ref_binds_ret_temp)
3094 << VD << RangeInitType;
3097 SemaRef.Diag(VD->getBeginLoc(), diag::note_use_non_reference_type)
3100 }
3101}
3102
3103
3104
3107 return RD->hasAttr();
3108
3109 return false;
3110}
3111
3112
3113
3114
3118 if (!InitExpr)
3119 return;
3120
3122
3123 if (const CXXConstructExpr *CE = dyn_cast(InitExpr)) {
3124 if (!CE->getConstructor()->isCopyConstructor())
3125 return;
3126 } else if (const CastExpr *CE = dyn_cast(InitExpr)) {
3127 if (CE->getCastKind() != CK_LValueToRValue)
3128 return;
3129 } else {
3130 return;
3131 }
3132
3133
3134
3135
3137 if (Ctx.getTypeSize(VariableType) <= 64 * 8 &&
3140 return;
3141
3142
3143
3144 SemaRef.Diag(VD->getLocation(), diag::warn_for_range_copy)
3145 << VD << VariableType;
3146 SemaRef.Diag(VD->getBeginLoc(), diag::note_use_reference_type)
3150}
3151
3152
3153
3154
3155
3156
3157
3158
3159
3163 return;
3164
3166 diag::warn_for_range_const_ref_binds_temp_built_from_ref,
3168 SemaRef.Diags.isIgnored(diag::warn_for_range_ref_binds_ret_temp,
3172 return;
3173 }
3174
3176 if (!VD)
3177 return;
3178
3180
3182 return;
3183
3185 if (!InitExpr)
3186 return;
3187
3189 return;
3190
3193 ForStmt->getRangeInit()->getType());
3196 }
3197}
3198
3200 if (!S || !B)
3202
3203 if (isa(S))
3205
3208
3210 diag::warn_empty_range_based_for_body);
3211
3213
3214 return S;
3215}
3216
3221
3222
3223
3224 if (getCurScope()->isInOpenACCComputeConstructScope())
3226
3228 return new (Context) GotoStmt(TheDecl, GotoLoc, LabelLoc);
3229}
3230
3234
3247 }
3248
3253
3255
3256
3257
3258 if (getCurScope()->isInOpenACCComputeConstructScope())
3260
3262}
3263
3265 const Scope &DestScope) {
3268 S.Diag(Loc, diag::warn_jump_out_of_seh_finally);
3269 }
3270}
3271
3275 if (!S) {
3276
3277 return StmtError(Diag(ContinueLoc, diag::err_continue_not_in_loop));
3278 }
3279 if (S->isConditionVarScope()) {
3280
3281
3282
3283 return StmtError(Diag(ContinueLoc, diag::err_continue_from_cond_var_init));
3284 }
3285
3286
3287
3288
3289 if (S->isOpenACCComputeConstructScope())
3291 Diag(ContinueLoc, diag::err_acc_branch_in_out_compute_construct)
3292 << 0 << 0);
3293
3295
3297}
3298
3302 if (!S) {
3303
3304 return StmtError(Diag(BreakLoc, diag::err_break_not_in_loop_or_switch));
3305 }
3306 if (S->isOpenMPLoopScope())
3307 return StmtError(Diag(BreakLoc, diag::err_omp_loop_cannot_use_stmt)
3308 << "break");
3309
3310
3311
3312
3313
3314
3315
3316
3317 if (S->isOpenACCComputeConstructScope() ||
3318 (S->isLoopScope() && S->getParent() &&
3319 S->getParent()->isOpenACCComputeConstructScope()))
3321 Diag(BreakLoc, diag::err_acc_branch_in_out_compute_construct)
3322 << 0 << 0);
3323
3325
3327}
3328
3331 if ()
3333
3334
3335 const auto *DR = dyn_cast(E->IgnoreParens());
3336 if (!DR || DR->refersToEnclosingVariableOrCapture())
3338 const auto *VD = dyn_cast(DR->getDecl());
3339 if (!VD)
3351 }
3352 return Res;
3353}
3354
3357
3358
3359
3360
3361 if (VD->getKind() == Decl::ParmVar)
3363 else if (VD->getKind() != Decl::Var)
3365
3366
3369
3370
3373
3374
3375
3376 if (VD->hasAttr())
3378
3381
3382
3386
3387
3388
3394 } else {
3396 }
3397
3398
3399
3403
3404 return Info;
3405}
3406
3410 return nullptr;
3411
3412 auto invalidNRVO = [&] {
3414 return nullptr;
3415 };
3416
3417
3418
3419
3420
3421 if ((ReturnType->getTypeClass() == Type::TypeClass::Auto &&
3424 return invalidNRVO();
3425
3427
3428
3430 return invalidNRVO();
3431
3433
3434
3438 }
3440}
3441
3442
3443
3444
3445
3446
3447static bool
3450 const auto *Step = llvm::find_if(Seq.steps(), [](const auto &Step) {
3451 return Step.Kind == InitializationSequence::SK_ConstructorInitialization ||
3452 Step.Kind == InitializationSequence::SK_UserConversion;
3453 });
3454 if (Step != Seq.step_end()) {
3455 const auto *FD = Step->Function.Function;
3456 if (isa(FD)
3458 : cast(FD)->getRefQualifier() == RQ_None)
3459 return false;
3460 }
3461 return true;
3462}
3463
3466 bool SupressSimplerImplicitMoves) {
3472 Expr *InitExpr = &AsRvalue;
3474 Value->getBeginLoc());
3476 auto Res = Seq.getFailedOverloadResult();
3480
3481
3485
3486
3487 return Seq.Perform(*this, Entity, Kind, Value);
3488 }
3489 }
3490
3491
3492
3494}
3495
3496
3497
3502}
3503
3505 Expr *RetValExp,
3507 bool SupressSimplerImplicitMoves) {
3508
3509
3512 LambdaScopeInfo *CurLambda = dyn_cast(CurCap);
3515 bool HasDeducedReturnType =
3517
3518 if (ExprEvalContexts.back().isDiscardedStatementContext() &&
3520 if (RetValExp) {
3525 RetValExp = ER.get();
3526 }
3528 nullptr);
3529 }
3530
3531 if (HasDeducedReturnType) {
3533
3534
3535
3538
3539
3542
3544 assert(AT && "lost auto type from lambda return type");
3547
3549 }
3552
3553
3554
3555
3556 if (RetValExp && !isa(RetValExp)) {
3558 if (Result.isInvalid())
3560 RetValExp = Result.get();
3561
3562
3563
3564
3565
3568 else
3570 } else {
3571 if (RetValExp) {
3572
3573
3574
3575 Diag(ReturnLoc, diag::err_lambda_return_init_list)
3577 }
3578
3580 }
3581
3582
3583
3586 }
3588
3589 if (auto *CurBlock = dyn_cast(CurCap)) {
3591 Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr);
3593 }
3594 } else if (auto *CurRegion = dyn_cast(CurCap)) {
3595 Diag(ReturnLoc, diag::err_return_in_captured_stmt) << CurRegion->getRegionName();
3597 } else {
3598 assert(CurLambda && "unknown kind of captured scope");
3602 Diag(ReturnLoc, diag::err_noreturn_lambda_has_return_expr);
3604 }
3605 }
3606
3607
3608
3609
3611
3612
3613 } else if (FnRetType->isVoidType()) {
3614 if (RetValExp && !isa(RetValExp) &&
3620 Diag(ReturnLoc, diag::ext_return_has_void_expr) << "literal" << 2;
3621 else {
3622 Diag(ReturnLoc, diag::err_return_block_has_expr);
3623 RetValExp = nullptr;
3624 }
3625 }
3626 } else if (!RetValExp) {
3627 return StmtError(Diag(ReturnLoc, diag::err_block_return_missing_expr));
3629
3630
3631
3632
3633
3634
3635
3636
3640 Entity, NRInfo, RetValExp, SupressSimplerImplicitMoves);
3642
3644 }
3645 RetValExp = Res.get();
3646 CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc);
3647 }
3648
3649 if (RetValExp) {
3654 RetValExp = ER.get();
3655 }
3658
3659
3660
3661
3664
3665 if (FunctionScopes.back()->FirstReturnLoc.isInvalid())
3667
3668 if (auto *CurBlock = dyn_cast(CurCap);
3671 CurBlock->TheDecl->setInvalidDecl();
3672
3674}
3675
3676namespace {
3677
3678
3679
3680
3681
3682
3683
3684
3685
3686
3687
3688
3690public:
3691 LocalTypedefNameReferencer(Sema &S) : S(S) {}
3692 bool VisitRecordType(RecordType *RT) override;
3693
3694private:
3696};
3697bool LocalTypedefNameReferencer::VisitRecordType(RecordType *RT) {
3698 auto *R = dyn_cast(RT->getDecl());
3699 if (!R || !R->isLocalClass() || !R->isLocalClass()->isExternallyVisible() ||
3700 R->isDependentType())
3701 return true;
3702 for (auto *TmpD : R->decls())
3703 if (auto *T = dyn_cast(TmpD))
3704 if (T->getAccess() != AS_private || R->hasFriends())
3706 return true;
3707}
3708}
3709
3714 .getReturnLoc();
3715}
3716
3720
3721
3722
3724 return false;
3725
3726 if (isa_and_nonnull(RetExpr)) {
3727
3728
3730 getCurLambda() ? diag::err_lambda_return_init_list
3731 : diag::err_auto_fn_return_init_list)
3733 return true;
3734 }
3735
3737
3738
3739
3740
3741 assert(AT->isDeduced() && "should have deduced to dependent type");
3742 return false;
3743 }
3744
3746
3747
3749 if (!RetExpr) {
3750
3751
3752
3753
3755 Diag(ReturnLoc, diag::err_auto_fn_return_void_but_not_auto)
3756 << OrigResultType.getType();
3757 return true;
3758 }
3759 RetExpr = &VoidVal;
3760 }
3761
3763 {
3764
3765
3766 auto RetExprLoc = RetExpr->getExprLoc();
3771 if (FindResult.Expression)
3772 TemplateSpecLoc = FindResult.Expression->getNameLoc();
3773 }
3776 OrigResultType, RetExpr, Deduced, Info, false,
3777 false, &FailedTSC);
3779 return true;
3780 switch (Res) {
3782 break;
3784 return true;
3786
3787
3788
3789
3792 Diag(ReturnLoc, diag::err_typecheck_missing_return_type_incompatible)
3794 else
3795 Diag(ReturnLoc, diag::err_auto_fn_different_deductions)
3798 return true;
3799 }
3800 default:
3801 Diag(RetExpr->getExprLoc(), diag::err_auto_fn_deduction_failure)
3804 return true;
3805 }
3806 }
3807
3808
3809
3810 LocalTypedefNameReferencer(*this).TraverseType(RetExpr->getType());
3811
3812
3815 Diag(FD->getLocation(), diag::err_kern_type_not_void_return)
3817 return true;
3818 }
3819
3821
3823
3824 return false;
3825}
3826
3829 Scope *CurScope) {
3830
3831
3833 RetValExp, nullptr, true);
3836
3837 if (getCurScope()->isInOpenACCComputeConstructScope())
3839 Diag(ReturnLoc, diag::err_acc_branch_in_out_compute_construct)
3840 << 1 << 0);
3841
3842
3846 "first coroutine location not set");
3847 Diag(ReturnLoc, diag::err_return_in_coroutine);
3850 }
3851
3852 CheckInvalidBuiltinCountedByRef(RetVal.get(), ReturnArgKind);
3853
3857 return R;
3858
3860 const_cast<VarDecl *>(cast(R.get())->getNRVOCandidate());
3861
3863
3865
3866 return R;
3867}
3868
3872 return false;
3875 return false;
3878 return true;
3879 }
3880 return false;
3881}
3882
3884 bool AllowRecovery) {
3885
3888
3889
3890
3891
3892 bool SupressSimplerImplicitMoves =
3897
3900 SupressSimplerImplicitMoves);
3901
3904 const AttrVec *Attrs = nullptr;
3905 bool isObjCMethod = false;
3906
3912 Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr) << FD;
3913 if (FD->isMain() && RetValExp)
3914 if (isa(RetValExp))
3915 Diag(ReturnLoc, diag::warn_main_returns_bool_literal)
3917 if (FD->hasAttr() && RetValExp) {
3918 if (const auto *RT = dyn_cast(FnRetType.getCanonicalType())) {
3920 Diag(RetValExp->getBeginLoc(), diag::warn_cmse_nonsecure_union) << 1;
3921 }
3922 }
3925 isObjCMethod = true;
3929
3930
3931
3934 }
3935 } else
3937
3938 if (RetValExp) {
3939 const auto *ATy = dyn_cast(RetValExp->getType());
3940 if (ATy && ATy->getElementType().isWebAssemblyReferenceType()) {
3941 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
3943 }
3944 }
3945
3946
3947
3948 if (ExprEvalContexts.back().isDiscardedStatementContext() &&
3950 if (RetValExp) {
3955 RetValExp = ER.get();
3956 }
3958 nullptr);
3959 }
3960
3961
3962
3966
3967
3968
3969
3973 if (!AllowRecovery)
3975
3976 if (RetValExp) {
3977
3978
3981 AT->isDeduced() ? FnRetType : QualType());
3982 if (Recovery.isInvalid())
3984 RetValExp = Recovery.get();
3985 } else {
3986
3987 }
3988 } else {
3990 }
3991 }
3992 }
3994
3995 bool HasDependentReturnType = FnRetType->isDependentType();
3996
3999 if (RetValExp) {
4000 if (auto *ILE = dyn_cast(RetValExp)) {
4001
4002
4003
4005 int FunctionKind = 0;
4006 if (isa(CurDecl))
4007 FunctionKind = 1;
4008 else if (isa(CurDecl))
4009 FunctionKind = 2;
4010 else if (isa(CurDecl))
4011 FunctionKind = 3;
4012
4013 Diag(ReturnLoc, diag::err_return_init_list)
4014 << CurDecl << FunctionKind << RetValExp->getSourceRange();
4015
4016
4017 RetValExp = AllowRecovery
4019 ILE->getRBraceLoc(), ILE->inits())
4021 : nullptr;
4023
4024 unsigned D = diag::ext_return_has_expr;
4027 if (isa(CurDecl) ||
4028 isa(CurDecl))
4029 D = diag::err_ctor_dtor_returns_void;
4030 else
4031 D = diag::ext_return_has_void_expr;
4032 }
4033 else {
4036 if (Result.isInvalid())
4038 RetValExp = Result.get();
4041 }
4042
4043 if (D == diag::err_ctor_dtor_returns_void) {
4045 Diag(ReturnLoc, D) << CurDecl << isa(CurDecl)
4047 }
4048
4049 else if (D != diag::ext_return_has_void_expr ||
4052
4053 int FunctionKind = 0;
4054 if (isa(CurDecl))
4055 FunctionKind = 1;
4056 else if (isa(CurDecl))
4057 FunctionKind = 2;
4058 else if (isa(CurDecl))
4059 FunctionKind = 3;
4060
4062 << CurDecl << FunctionKind << RetValExp->getSourceRange();
4063 }
4064 }
4065
4066 if (RetValExp) {
4071 RetValExp = ER.get();
4072 }
4073 }
4074
4076 nullptr);
4077 } else if (!RetValExp && !HasDependentReturnType) {
4079
4081
4083
4084 Diag(ReturnLoc, diag::err_constexpr_return_missing_expr)
4087 } else {
4088
4089
4090 unsigned DiagID = getLangOpts().C99 ? diag::ext_return_missing_expr
4091 : diag::warn_return_missing_expr;
4092
4093
4095 "Not in a FunctionDecl or ObjCMethodDecl?");
4096 bool IsMethod = FD == nullptr;
4098 IsMethod ? cast(getCurMethodDecl()) : cast(FD);
4099 Diag(ReturnLoc, DiagID) << ND << IsMethod;
4100 }
4101
4103 nullptr);
4104 } else {
4105 assert(RetValExp || HasDependentReturnType);
4106 QualType RetType = RelatedRetType.isNull() ? FnRetType : RelatedRetType;
4107
4108
4109
4110
4111
4112
4113
4114 if (!HasDependentReturnType && !RetValExp->isTypeDependent()) {
4115
4119 Entity, NRInfo, RetValExp, SupressSimplerImplicitMoves);
4120 if (Res.isInvalid() && AllowRecovery)
4122 RetValExp->getEndLoc(), RetValExp, RetType);
4124
4126 }
4128
4129
4130
4131
4132
4133 if (!RelatedRetType.isNull()) {
4135 FnRetType);
4138
4140 }
4142 }
4143
4144 CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc, isObjCMethod, Attrs,
4146 }
4147
4148 if (RetValExp) {
4153 RetValExp = ER.get();
4154 }
4156 }
4157
4158
4159
4160 if (Result->getNRVOCandidate())
4162
4163 if (FunctionScopes.back()->FirstReturnLoc.isInvalid())
4165
4167}
4168
4171 Stmt *HandlerBlock) {
4172
4174 CXXCatchStmt(CatchLoc, cast_or_null(ExDecl), HandlerBlock);
4175}
4176
4177namespace {
4178class CatchHandlerType {
4180 LLVM_PREFERRED_TYPE(bool)
4181 unsigned IsPointer : 1;
4182
4183
4184
4185 friend struct llvm::DenseMapInfo;
4186 enum Unique { ForDenseMap };
4187 CatchHandlerType(QualType QT, Unique) : QT(QT), IsPointer(false) {}
4188
4189public:
4190
4191
4192
4193 CatchHandlerType(QualType Q) : QT(Q), IsPointer(false) {
4195 IsPointer = true;
4196
4200 }
4201
4202
4203
4204
4205 CatchHandlerType(QualType QT, bool IsPointer)
4206 : QT(QT), IsPointer(IsPointer) {}
4207
4208 QualType underlying() const { return QT; }
4209 bool isPointer() const { return IsPointer; }
4210
4211 friend bool operator==(const CatchHandlerType &LHS,
4212 const CatchHandlerType &RHS) {
4213
4214 if (LHS.IsPointer != RHS.IsPointer)
4215 return false;
4216
4217 return LHS.QT == RHS.QT;
4218 }
4219};
4220}
4221
4222namespace llvm {
4223template <> struct DenseMapInfo {
4225 return CatchHandlerType(DenseMapInfo::getEmptyKey(),
4226 CatchHandlerType::ForDenseMap);
4227 }
4228
4230 return CatchHandlerType(DenseMapInfo::getTombstoneKey(),
4231 CatchHandlerType::ForDenseMap);
4232 }
4233
4235 return DenseMapInfo::getHashValue(Base.underlying());
4236 }
4237
4238 static bool isEqual(const CatchHandlerType &LHS,
4239 const CatchHandlerType &RHS) {
4240 return LHS == RHS;
4241 }
4242};
4243}
4244
4245namespace {
4246class CatchTypePublicBases {
4247 const llvm::DenseMap<QualType, CXXCatchStmt *> &TypesToCheck;
4248
4252
4253public:
4254 CatchTypePublicBases(const llvm::DenseMap<QualType, CXXCatchStmt *> &T,
4256 : TypesToCheck(T), FoundHandler(nullptr), TestAgainstType(QT) {}
4257
4258 CXXCatchStmt *getFoundHandler() const { return FoundHandler; }
4259 QualType getFoundHandlerType() const { return FoundHandlerType; }
4260
4262 if (S->getAccessSpecifier() == AccessSpecifier::AS_public) {
4263 QualType Check = S->getType().getCanonicalType();
4264 const auto &M = TypesToCheck;
4265 auto I = M.find(Check);
4266 if (I != M.end()) {
4267
4268
4269
4270
4271
4272
4273
4274
4275
4276
4277 if (I->second->getCaughtType()->isPointerType() ==
4279 FoundHandler = I->second;
4280 FoundHandlerType = Check;
4281 return true;
4282 }
4283 }
4284 }
4285 return false;
4286 }
4287};
4288}
4289
4293 const bool IsOpenMPGPUTarget =
4294 getLangOpts().OpenMPIsTargetDevice && (T.isNVPTX() || T.isAMDGCN());
4295
4296
4297 if (!IsOpenMPGPUTarget && ().CXXExceptions &&
4299
4300 targetDiag(TryLoc, diag::err_exceptions_disabled) << "try";
4301 }
4302
4303
4304
4305 if (IsOpenMPGPUTarget)
4306 targetDiag(TryLoc, diag::warn_try_not_valid_on_target) << T.str();
4307
4308
4311 << "try" << llvm::to_underlying(CUDA().CurrentTarget());
4312
4314 Diag(TryLoc, diag::err_omp_simd_region_cannot_use_stmt) << "try";
4315
4317
4318
4320 Diag(TryLoc, diag::err_mixing_cxx_try_seh_try) << 0;
4321 Diag(FSI->FirstSEHTryLoc, diag::note_conflicting_try_here) << "'__try'";
4322 }
4323
4324 const unsigned NumHandlers = Handlers.size();
4325 assert(!Handlers.empty() &&
4326 "The parser shouldn't call this if there are no handlers.");
4327
4328 llvm::DenseMap<QualType, CXXCatchStmt *> HandledBaseTypes;
4329 llvm::DenseMap<CatchHandlerType, CXXCatchStmt *> HandledTypes;
4330 for (unsigned i = 0; i < NumHandlers; ++i) {
4331 CXXCatchStmt *H = cast(Handlers[i]);
4332
4333
4334
4335
4337 if (i < NumHandlers - 1)
4339 continue;
4341 continue;
4342
4343
4344
4345
4347
4348
4349
4350
4351 QualType Underlying = HandlerCHT.underlying();
4353 if (!RD->hasDefinition())
4354 continue;
4355
4356
4357
4358
4359
4361 Paths.setOrigin(RD);
4362 CatchTypePublicBases CTPB(HandledBaseTypes,
4364 if (RD->lookupInBases(CTPB, Paths)) {
4365 const CXXCatchStmt *Problem = CTPB.getFoundHandler();
4366 if (!Paths.isAmbiguous(
4369 diag::warn_exception_caught_by_earlier_handler)
4372 diag::note_previous_exception_handler)
4374 }
4375 }
4376
4377
4378
4380 }
4381
4382
4383
4384 auto R = HandledTypes.insert(
4386 if (!R.second) {
4387 const CXXCatchStmt *Problem = R.first->second;
4389 diag::warn_exception_caught_by_earlier_handler)
4392 diag::note_previous_exception_handler)
4394 }
4395 }
4396
4398
4400 Handlers);
4401}
4402
4404 Stmt *TryBlock, Stmt *Handler) {
4405 assert(TryBlock && Handler);
4406
4408
4409
4410
4413 Diag(TryLoc, diag::err_mixing_cxx_try_seh_try) << FSI->FirstTryType;
4416 ? "'try'"
4417 : "'@try'");
4418 }
4419 }
4420
4422
4423
4424
4428 FunctionDecl *FD = dyn_cast_or_null(DC);
4429 if (FD)
4431 else
4432 Diag(TryLoc, diag::err_seh_try_outside_functions);
4433
4434
4436 Diag(TryLoc, diag::err_seh_try_unsupported);
4437
4439}
4440
4443 assert(FilterExpr && Block);
4447 Diag(FilterExpr->getExprLoc(), diag::err_filter_expression_integral)
4448 << FTy);
4449 }
4451}
4452
4455}
4456
4459}
4460
4465}
4466
4469 Scope *SEHTryParent = CurScope;
4470 while (SEHTryParent && !SEHTryParent->isSEHTryScope())
4471 SEHTryParent = SEHTryParent->getParent();
4472 if (!SEHTryParent)
4473 return StmtError(Diag(Loc, diag::err_ms___leave_not_in___try));
4475
4477}
4478
4480 bool IsIfExists,
4483 Stmt *Nested)
4484{
4486 QualifierLoc, NameInfo,
4487 cast(Nested));
4488}
4489
4490
4492 bool IsIfExists,
4495 Stmt *Nested) {
4499 Nested);
4500}
4501
4504 unsigned NumParams) {
4508
4512 nullptr);
4513 else
4515 nullptr);
4516
4521
4522 assert(NumParams > 0 && "CapturedStmt requires context parameter");
4525 return RD;
4526}
4527
4528static bool
4534 continue;
4535
4536
4539
4540
4541
4542
4543
4545
4546
4551 Captures.push_back(
4553 } else {
4555
4559
4565 }
4566 CaptureInits.push_back(Init.get());
4567 }
4568 return false;
4569}
4570
4573 unsigned NumParams) {
4576
4577
4581 auto *Param =
4585
4587
4588
4590
4591 if (CurScope)
4593 else
4595
4598 ExprEvalContexts.back().InImmediateEscalatingFunctionContext = false;
4599}
4600
4604 unsigned OpenMPCaptureLevel) {
4607
4608
4610 bool ContextIsFound = false;
4611 unsigned ParamNum = 0;
4613 E = Params.end();
4614 I != E; ++I, ++ParamNum) {
4615 if (I->second.isNull()) {
4616 assert(!ContextIsFound &&
4617 "null type has been found already for '__context' parameter");
4622 auto *Param =
4627 ContextIsFound = true;
4628 } else {
4630 auto *Param =
4634 CD->setParam(ParamNum, Param);
4635 }
4636 }
4637 assert(ContextIsFound && "no null type for '__context' parameter");
4638 if (!ContextIsFound) {
4639
4642 auto *Param =
4647 }
4648
4650
4651 if (CurScope)
4653 else
4655
4658}
4659
4666
4669
4673}
4674
4676
4677
4683
4688
4691
4694 Captures, CaptureInits, CD, RD);
4695
4698
4699 return Res;
4700}
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::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.
static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init, SourceLocation Loc, int DiagID)
Finish building a variable declaration for a for-range statement.
static bool CmpCaseVals(const std::pair< llvm::APSInt, CaseStmt * > &lhs, const std::pair< llvm::APSInt, CaseStmt * > &rhs)
CmpCaseVals - Comparison predicate for sorting case values.
SmallVector< std::pair< llvm::APSInt, EnumConstantDecl * >, 64 > EnumValsTy
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...
static bool DiagnoseUnusedComparison(Sema &S, const Expr *E)
Diagnose unused comparisons, both builtin and overloaded operators.
static bool EqEnumVals(const std::pair< llvm::APSInt, EnumConstantDecl * > &lhs, const std::pair< llvm::APSInt, EnumConstantDecl * > &rhs)
EqEnumVals - Comparison preficate for uniqing enumeration values.
static bool hasDeducedReturnType(FunctionDecl *FD)
Determine whether the declared return type of the specified function contains 'auto'.
static bool ObjCEnumerationCollection(Expr *Collection)
static void DiagnoseForRangeConstVariableCopies(Sema &SemaRef, const VarDecl *VD)
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.
static void checkEnumTypesInSwitchStmt(Sema &S, const Expr *Cond, const Expr *Case)
static void DiagnoseForRangeReferenceVariableCopies(Sema &SemaRef, const VarDecl *VD, QualType RangeInitType)
static void DiagnoseForRangeVariableCopies(Sema &SemaRef, const CXXForRangeStmt *ForStmt)
DiagnoseForRangeVariableCopies - Diagnose three cases and fixes for them.
static bool CheckSimplerImplicitMovesMSVCWorkaround(const Sema &S, const Expr *E)
static bool VerifyInitializationSequenceCXX98(const Sema &S, const InitializationSequence &Seq)
Verify that the initialization sequence that was picked for the first overload resolution is permissi...
static QualType GetTypeBeforeIntegralPromotion(const Expr *&E)
GetTypeBeforeIntegralPromotion - Returns the pre-promotion type of potentially integral-promoted expr...
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.
static bool hasTrivialABIAttr(QualType VariableType)
Determines whether the VariableType's declaration is a record with the clang::trivial_abi attribute.
static void AdjustAPSInt(llvm::APSInt &Val, unsigned BitWidth, bool IsSigned)
static bool buildCapturedStmtCaptureList(Sema &S, CapturedRegionScopeInfo *RSI, SmallVectorImpl< CapturedStmt::Capture > &Captures, SmallVectorImpl< Expr * > &CaptureInits)
static bool DiagnoseNoDiscard(Sema &S, const NamedDecl *OffendingDecl, const WarnUnusedResultAttr *A, SourceLocation Loc, SourceRange R1, SourceRange R2, bool IsCtor)
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.
static void CheckJumpOutOfSEHFinally(Sema &S, SourceLocation Loc, const Scope &DestScope)
Defines the Objective-C statement AST node classes.
enum clang::format::@1338::AnnotatingParser::Context::@353 ContextType
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 ...
SourceManager & getSourceManager()
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
QualType getAutoRRefDeductType() const
C++11 deduction pattern for 'auto &&' type.
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
bool hasSimilarType(QualType T1, QualType T2) const
Determine if two types are similar, according to the C++ rules.
const TargetInfo & getTargetInfo() const
QualType getAutoDeductType() const
C++11 deduction pattern for 'auto' type.
void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType)
Change the result type of a function type once it is deduced.
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)
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
bool isDecltypeAuto() const
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
A builtin binary operation expression such as "x + y" or "x <= y".
BreakStmt - This represents a break.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Represents a base class of a C++ class.
Represents binding an expression to a temporary.
A boolean literal, per ([C++ lex.bool] Boolean literals).
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++ constructor within a class.
Represents a C++ conversion function within a class.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
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....
Represents a static or instance method of a struct/union/class.
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, bool DelayTypeCreation=false)
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)
Builds a canonical type from a QualType.
QualType withConst() const
Retrieves a version of this type with const applied.
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...
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)
ConditionalOperator - The ?: ternary operator.
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
QualType getDeducedType() const
Get the type deduced for this placeholder type, or null if it has not been deduced.
SourceLocation getDefaultLoc() const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
DoStmt - This represents a 'do/while' stmt.
Recursive AST visitor that supports extension via dynamic dispatch.
enumerator_range enumerators() const
bool isClosed() const
Returns true if this enum is either annotated with enum_extensibility(closed) or isn't annotated with...
bool isClosedNonFlag() const
Returns true if this enum is annotated with neither flag_enum nor enum_extensibility(open).
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
EnumDecl * getDecl() const
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, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Decl * getReferencedDeclOfCallee()
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
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
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
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.
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
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
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.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
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.
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.
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
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.
Represents Objective-C's collection statement.
An expression that sends a message to the given Objective-C object or class.
ObjCMethodDecl - Represents an instance or class method declaration.
bool hasRelatedResultType() const
Determine whether this method has a result type that is related to the message receiver's type.
QualType getReturnType() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
Wrapper for void* pointer.
void * getAsOpaquePtr() const
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.
ParenExpr - This represents a parenthesized expression, e.g.
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 withRestrict() const
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.
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)
bool isOrContainsUnion() const
Returns whether this record is a union, or contains (at any nesting level) a union member.
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.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
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.
const Scope * getFnParent() const
getFnParent - Return the closest scope that is a function body.
bool Contains(const Scope &rhs) const
Returns if rhs has a higher scope depth than this.
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 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.
void updateNRVOCandidate(VarDecl *VD)
@ SwitchScope
This is a scope that corresponds to a switch statement.
A generic diagnostic builder for errors which may or may not be deferred.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
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.
void DiagnoseDiscardedExprMarkedNodiscard(const Expr *E)
DiagnoseDiscardedExprMarkedNodiscard - Given an expression that is semantically a discarded-value exp...
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)
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)
StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope)
StmtResult ActOnForEachLValueExpr(Expr *E)
In an Objective C collection iteration statement: for (x in y) x can be an arbitrary l-value expressi...
void ActOnForEachDeclStmt(DeclGroupPtrTy Decl)
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...
StmtResult ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, LabelDecl *TheDecl)
StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, Scope *CurScope)
void setFunctionHasBranchIntoScope()
ExprResult ActOnCaseExpr(SourceLocation CaseLoc, ExprResult Val)
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, AllowFoldKind CanFold=NoFold)
VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...
StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue=true)
FieldDecl * BuildCaptureField(RecordDecl *RD, const sema::Capture &Capture)
Build a FieldDecl suitable to hold the given capture.
StmtResult BuildIfStmt(SourceLocation IfLoc, IfStatementKind StatementKind, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc, Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal)
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.
ExprResult CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond)
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()
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ASTContext & getASTContext() const
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)
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)
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...
std::unique_ptr< sema::FunctionScopeInfo, PoppedFunctionScopeDeleter > PoppedFunctionScopePtr
void DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID)
DiagnoseUnusedExprResult - If the statement passed in is an expression whose result is unused,...
FPOptions & getCurFPFeatures()
@ UPPC_Expression
An arbitrary expression.
const LangOptions & getLangOpts() const
StmtResult ActOnWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, ConditionResult Cond, SourceLocation RParenLoc, Stmt *Body)
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)
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....
void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool MightBeOdrUse)
Perform marking for a reference to an arbitrary declaration.
TypeLoc getReturnTypeLoc(FunctionDecl *FD) const
StmtResult ActOnExprStmtError()
const VarDecl * getCopyElisionCandidate(NamedReturnInfo &Info, QualType ReturnType)
Updates given NamedReturnInfo's move-eligible and copy-elidable statuses, considering the function re...
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)
RecordDecl * CreateCapturedStmtRecordDecl(CapturedDecl *&CD, SourceLocation Loc, unsigned NumParams)
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams)
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...
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.
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...
ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E)
std::optional< sema::TemplateDeductionInfo * > isSFINAEContext() const
Determines whether we are currently in a context where template argument substitution failures are no...
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.
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.
AssignConvertType
AssignConvertType - All of the 'assignment' semantic checks return this enum to indicate whether the ...
StmtResult ActOnCapturedRegionEnd(Stmt *S)
StmtResult ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, Stmt *First, ConditionResult Second, FullExprArg Third, SourceLocation RParenLoc, Stmt *Body)
StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, Expr *DestExp)
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.
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.
StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, bool AllowRecovery=false)
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)
StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope)
@ CCEK_CaseValue
Expression in a case label.
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.
StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, SourceLocation WhileLoc, SourceLocation CondLParen, Expr *Cond, SourceLocation CondRParen)
StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc)
StmtResult ActOnMSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, CXXScopeSpec &SS, UnqualifiedId &Name, Stmt *Nested)
@ 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)
void ActOnAfterCompoundStatementLeadingPragmas()
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
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)
SourceManager & SourceMgr
DiagnosticsEngine & Diags
StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope)
void ActOnStartSEHFinallyBlock()
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void ActOnAbortSEHFinallyBlock()
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...
void ActOnCaseStmtBody(Stmt *CaseStmt, Stmt *SubStmt)
ActOnCaseStmtBody - This installs a statement as the body of a case.
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)
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
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()
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)
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)
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...
StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, Stmt *SubStmt, Scope *CurScope)
StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHS, SourceLocation DotDotDotLoc, ExprResult RHS, SourceLocation ColonLoc)
StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body)
FinishCXXForRangeStmt - Attach the body to a C++0x for-range statement.
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
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
const SwitchCase * getNextSwitchCase() const
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()
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.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TypedefNameDecl * getTypedefNameForAnonDecl() const
void startDefinition()
Starts the definition of this tag declaration.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool isSEHTrySupported() const
Whether the target supports SEH __try.
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.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isRValueReferenceType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs.
bool isReferenceType() const
bool isEnumeralType() const
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.
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,...
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),...
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.
WhileStmt - This represents a 'while' stmt.
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::@247 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.
Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)
@ 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)
CapturedRegionKind
The different kinds of captured statement.
@ Result
The result type of a method or function.
ActionResult< Expr * > ExprResult
@ Struct
The "struct" keyword.
bool isLambdaConversionOperator(CXXConversionDecl *C)
ActionResult< Stmt * > StmtResult
@ 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)
const FunctionProtoType * T
Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
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.
@ CapturedContext
Parameter for captured context.
Diagnostic wrappers for TextAPI types for error reporting.
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()
static CatchHandlerType getTombstoneKey()
static unsigned getHashValue(const CatchHandlerType &Base)
static bool isEqual(const CatchHandlerType &LHS, const CatchHandlerType &RHS)