39#include "llvm/ADT/ArrayRef.h"
40#include "llvm/ADT/DenseMap.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/SmallVector.h"
43#include "llvm/ADT/StringExtras.h"
71 bool HasLeadingEmptyMacro) {
100 Diag(
decl->getLocation(), diag::err_non_variable_decl_in_for);
101 decl->setInvalidDecl();
107 var->setInit(
nullptr);
120 var->setType(
type.withConst());
121 var->setARCPseudoStrong(
true);
134 enum { Equality, Inequality, Relational, ThreeWay } Kind;
137 if (!Op->isComparisonOp())
140 if (Op->getOpcode() == BO_EQ)
142 else if (Op->getOpcode() == BO_NE)
144 else if (Op->getOpcode() == BO_Cmp)
147 assert(Op->isRelationalOp());
150 Loc = Op->getOperatorLoc();
151 CanAssign = Op->getLHS()->IgnoreParenImpCasts()->isLValue();
153 switch (Op->getOperator()) {
157 case OO_ExclaimEqual:
162 case OO_GreaterEqual:
173 Loc = Op->getOperatorLoc();
174 CanAssign = Op->getArg(0)->IgnoreParenImpCasts()->isLValue();
185 S.
Diag(Loc, diag::warn_unused_comparison)
191 if (Kind == Inequality)
192 S.
Diag(Loc, diag::note_inequality_comparison_to_or_assign)
194 else if (Kind == Equality)
195 S.
Diag(Loc, diag::note_equality_comparison_to_assign)
207 StringRef Msg = A->getMessage();
211 return S.
Diag(Loc, diag::warn_unused_return_type)
212 << IsCtor << A << OffendingDecl <<
false << R1 << R2;
214 return S.
Diag(Loc, diag::warn_unused_constructor)
215 << A <<
false << R1 << R2;
216 return S.
Diag(Loc, diag::warn_unused_result) << A <<
false << R1 << R2;
220 return S.
Diag(Loc, diag::warn_unused_return_type)
221 << IsCtor << A << OffendingDecl <<
true << Msg << R1 << R2;
223 return S.
Diag(Loc, diag::warn_unused_constructor)
224 << A <<
true << Msg << R1 << R2;
225 return S.
Diag(Loc, diag::warn_unused_result) << A <<
true << Msg << R1 << R2;
234void DiagnoseUnused(
Sema &S,
const Expr *E, std::optional<unsigned> DiagID) {
235 bool NoDiscardOnly = !DiagID.has_value();
251 const Expr *WarnExpr;
257 if (!NoDiscardOnly) {
278 if (
const FullExpr *Temps = dyn_cast<FullExpr>(E))
279 E = Temps->getSubExpr();
281 E = TempExpr->getSubExpr();
287 if (
const auto *Cast = dyn_cast<CastExpr>(E))
288 if (
Cast->getCastKind() == CK_NoOp ||
289 Cast->getCastKind() == CK_ConstructorConversion ||
290 Cast->getCastKind() == CK_IntegralCast)
291 E =
Cast->getSubExpr()->IgnoreImpCasts();
293 if (
const CallExpr *CE = dyn_cast<CallExpr>(E)) {
297 auto [OffendingDecl, A] = CE->getUnusedResultAttr(S.
Context);
306 if (
const Decl *FD = CE->getCalleeDecl()) {
309 if (FD->hasAttr<PureAttr>()) {
310 S.
Diag(Loc, diag::warn_unused_call) << R1 << R2 <<
"pure";
313 if (FD->hasAttr<ConstAttr>()) {
314 S.
Diag(Loc, diag::warn_unused_call) << R1 << R2 <<
"const";
318 }
else if (
const auto *CE = dyn_cast<CXXConstructExpr>(E)) {
319 auto [OffendingDecl, A] = CE->getUnusedResultAttr(S.
Context);
323 }
else if (
const auto *ILE = dyn_cast<InitListExpr>(E)) {
324 if (
const TagDecl *TD = ILE->getType()->getAsTagDecl()) {
330 }
else if (ShouldSuppress)
335 if (S.
getLangOpts().ObjCAutoRefCount && ME->isDelegateInitCall()) {
336 S.
Diag(Loc, diag::err_arc_unused_init_message) << R1;
340 auto [OffendingDecl, A] = ME->getUnusedResultAttr(S.
Context);
345 const Expr *Source = POE->getSyntacticForm();
348 POE->getNumSemanticExprs() == 1 &&
350 return DiagnoseUnused(S, POE->getSemanticExpr(0), DiagID);
352 DiagID = diag::warn_unused_container_subscript_expr;
354 DiagID = diag::warn_unused_property_expr;
356 = dyn_cast<CXXFunctionalCastExpr>(E)) {
357 const Expr *E = FC->getSubExpr();
359 E = TE->getSubExpr();
363 if (
const CXXRecordDecl *RD = CE->getType()->getAsCXXRecordDecl())
364 if (!RD->getAttr<WarnUnusedAttr>())
380 S.
Diag(Loc, diag::warn_unused_voidptr)
390 S.
Diag(Loc, diag::warn_unused_volatile) << R1 << R2;
397 if (DiagID == diag::warn_unused_comma_left_operand && S.
isSFINAEContext())
401 S.
PDiag(*DiagID) << R1 << R2);
406 if (
const LabelStmt *Label = dyn_cast_if_present<LabelStmt>(S))
407 S = Label->getSubStmt();
409 const Expr *E = dyn_cast_if_present<Expr>(S);
413 DiagnoseUnused(*
this, E, DiagID);
438 const unsigned NumElts = Elts.size();
443 const unsigned MixedDeclsCodeID =
getLangOpts().C99
444 ? diag::warn_mixed_decls_code
445 : diag::ext_mixed_decls_code;
468 for (
unsigned i = 0; i != NumElts - 1; ++i)
504 auto CheckAndFinish = [&](
Expr *E) {
511 llvm::APSInt TempVal;
528 return CheckAndFinish(Val.
get());
535 assert((LHSVal.
isInvalid() || LHSVal.
get()) &&
"missing LHS value");
538 "missing RHS value");
541 Diag(CaseLoc, diag::err_case_not_in_switch);
552 Diag(CaseLoc, diag::err_acc_branch_in_out_compute_construct)
558 CaseLoc, DotDotDotLoc, ColonLoc);
571 Diag(DefaultLoc, diag::err_default_not_in_switch);
577 Diag(DefaultLoc, diag::err_acc_branch_in_out_compute_construct)
592 Diag(IdentLoc, diag::err_redefinition_of_label) << TheDecl->
getDeclName();
599 !
Context.getSourceManager().isInSystemHeader(IdentLoc))
600 Diag(IdentLoc, diag::warn_reserved_extern_symbol)
601 << TheDecl << static_cast<int>(Status);
605 if (
getCurScope()->isInOpenACCComputeConstructScope())
636 for (
const auto *A : Attrs) {
637 if (A->getKind() == attr::MustTail) {
652 if (!SemanticAttrs.empty())
668 if (!checkMustTailAttr(St, MTA))
674 auto IgnoreImplicitAsWritten = [](
Expr *E) ->
Expr * {
685bool Sema::checkMustTailAttr(
const Stmt *St,
const Attr &MTA) {
687 "musttail cannot be checked from a dependent context");
690 auto IgnoreParenImplicitAsWritten = [](
const Expr *E) ->
const Expr * {
697 const auto *CE = dyn_cast_or_null<CallExpr>(IgnoreParenImplicitAsWritten(E));
704 if (
const FunctionDecl *CalleeDecl = CE->getDirectCallee();
705 CalleeDecl && CalleeDecl->hasAttr<NotTailCalledAttr>()) {
706 Diag(St->
getBeginLoc(), diag::err_musttail_mismatch) <<
true << CalleeDecl;
707 Diag(CalleeDecl->getLocation(), diag::note_musttail_disabled_by_not_tail_called);
711 if (
const auto *EWC = dyn_cast<ExprWithCleanups>(E)) {
712 if (EWC->cleanupsHaveSideEffects()) {
713 Diag(St->
getBeginLoc(), diag::err_musttail_needs_trivial_args) << &MTA;
724 ft_non_static_member,
725 ft_pointer_to_member,
726 } MemberType = ft_non_member;
729 const FunctionProtoType *
Func;
730 const CXXMethodDecl *
Method =
nullptr;
731 } CallerType, CalleeType;
733 auto GetMethodType = [
this, St, MTA](
const CXXMethodDecl *CMD, FuncType &
Type,
734 bool IsCallee) ->
bool {
737 << IsCallee << isa<CXXDestructorDecl>(CMD);
739 Diag(CMD->getBeginLoc(), diag::note_musttail_structors_forbidden)
745 Type.MemberType = FuncType::ft_static_member;
747 Type.This = CMD->getFunctionObjectParameterType();
748 Type.MemberType = FuncType::ft_non_static_member;
750 Type.Func = CMD->getType()->castAs<FunctionProtoType>();
754 const auto *CallerDecl = dyn_cast<FunctionDecl>(
CurContext);
765 Diag(St->
getBeginLoc(), diag::err_musttail_forbidden_from_this_context)
766 << &MTA << ContextType;
768 }
else if (
const auto *CMD = dyn_cast<CXXMethodDecl>(
CurContext)) {
770 if (!GetMethodType(CMD, CallerType,
false))
774 CallerType.Func = CallerDecl->getType()->getAs<FunctionProtoType>();
777 const Expr *CalleeExpr = CE->getCallee()->IgnoreParens();
778 const auto *CalleeBinOp = dyn_cast<BinaryOperator>(CalleeExpr);
779 SourceLocation CalleeLoc = CE->getCalleeDecl()
780 ? CE->getCalleeDecl()->getBeginLoc()
784 if (
const CXXMethodDecl *CMD =
785 dyn_cast_or_null<CXXMethodDecl>(CE->getCalleeDecl())) {
787 if (!GetMethodType(CMD, CalleeType,
true))
789 }
else if (CalleeBinOp && CalleeBinOp->isPtrMemOp()) {
792 CalleeBinOp->getRHS()->getType()->castAs<MemberPointerType>();
794 Context.getCanonicalTagType(MPT->getMostRecentCXXRecordDecl());
795 CalleeType.Func = MPT->getPointeeType()->castAs<FunctionProtoType>();
796 CalleeType.MemberType = FuncType::ft_pointer_to_member;
809 if (!CalleeType.Func || !CallerType.Func) {
811 if (!CalleeType.Func && CE->getDirectCallee()) {
812 Diag(CE->getDirectCallee()->getBeginLoc(),
813 diag::note_musttail_fix_non_prototype);
815 if (!CallerType.Func)
816 Diag(CallerDecl->getBeginLoc(), diag::note_musttail_fix_non_prototype);
827 if (CallerType.Func->getCallConv() != CalleeType.Func->getCallConv()) {
828 if (
const auto *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl()))
830 <<
true << ND->getDeclName();
832 Diag(St->
getBeginLoc(), diag::err_musttail_callconv_mismatch) <<
false;
833 Diag(CalleeLoc, diag::note_musttail_callconv_mismatch)
840 if (CalleeType.Func->isVariadic() || CallerType.Func->isVariadic()) {
845 const auto *CalleeDecl = CE->getCalleeDecl();
846 if (CalleeDecl && CalleeDecl->hasAttr<CXX11NoReturnAttr>()) {
852 if (CallerType.This.isNull() != CalleeType.This.isNull()) {
853 if (
const auto *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl())) {
855 << CallerType.MemberType << CalleeType.MemberType <<
true
856 << ND->getDeclName();
857 Diag(CalleeLoc, diag::note_musttail_callee_defined_here)
858 << ND->getDeclName();
861 << CallerType.MemberType << CalleeType.MemberType <<
false;
866 auto CheckTypesMatch = [
this](FuncType CallerType, FuncType CalleeType,
867 PartialDiagnostic &PD) ->
bool {
875 auto DoTypesMatch = [
this, &PD](QualType A, QualType B,
876 unsigned Select) ->
bool {
877 if (!
Context.hasSimilarType(A, B)) {
884 if (!CallerType.This.isNull() &&
888 if (!DoTypesMatch(CallerType.Func->getReturnType(),
892 if (CallerType.Func->getNumParams() != CalleeType.Func->getNumParams()) {
894 << CalleeType.Func->getNumParams();
898 ArrayRef<QualType> CalleeParams = CalleeType.Func->getParamTypes();
899 ArrayRef<QualType> CallerParams = CallerType.Func->getParamTypes();
900 size_t N = CallerType.Func->getNumParams();
901 for (
size_t I = 0; I < N; I++) {
902 if (!DoTypesMatch(CalleeParams[I], CallerParams[I],
904 PD << static_cast<int>(I) + 1;
912 PartialDiagnostic PD =
PDiag(diag::note_musttail_mismatch);
913 if (!CheckTypesMatch(CallerType, CalleeType, PD)) {
914 if (
const auto *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl()))
916 <<
true << ND->getDeclName();
927 for (
auto ArgExpr : CE->arguments()) {
929 Context, ArgExpr->getType(),
false);
938 typedef EvaluatedExprVisitor<CommaVisitor> Inherited;
941 CommaVisitor(Sema &SemaRef) : Inherited(SemaRef.Context), SemaRef(SemaRef) {}
942 void VisitBinaryOperator(BinaryOperator *E) {
945 EvaluatedExprVisitor<CommaVisitor>::VisitBinaryOperator(E);
956 if (
Cond.isInvalid())
959 bool ConstevalOrNegatedConsteval =
964 assert((CondExpr || ConstevalOrNegatedConsteval) &&
965 "If statement: missing condition");
969 CommaVisitor(*this).Visit(CondExpr);
971 if (!ConstevalOrNegatedConsteval && !elseStmt)
974 if (ConstevalOrNegatedConsteval ||
976 auto DiagnoseLikelihood = [&](
const Stmt *S) {
978 Diags.Report(A->getLocation(),
979 diag::warn_attribute_has_no_effect_on_compile_time_if)
980 << A << ConstevalOrNegatedConsteval << A->getRange();
982 diag::note_attribute_has_no_effect_on_compile_time_if_here)
983 << ConstevalOrNegatedConsteval
990 DiagnoseLikelihood(thenStmt);
991 DiagnoseLikelihood(elseStmt);
993 std::tuple<bool, const Attr *, const Attr *> LHC =
995 if (std::get<0>(LHC)) {
996 const Attr *ThenAttr = std::get<1>(LHC);
997 const Attr *ElseAttr = std::get<2>(LHC);
999 diag::warn_attributes_likelihood_ifstmt_conflict)
1000 << ThenAttr << ThenAttr->
getRange();
1002 << ElseAttr << ElseAttr->
getRange();
1006 if (ConstevalOrNegatedConsteval) {
1012 if (FD && FD->isImmediateFunction())
1016 Diags.Report(IfLoc, diag::warn_consteval_if_always_true) << Immediate;
1028 return BuildIfStmt(IfLoc, StatementKind, LParenLoc, InitStmt,
Cond, RParenLoc,
1029 thenStmt, ElseLoc, elseStmt);
1038 if (
Cond.isInvalid())
1046 Cond.get().first,
Cond.get().second, LParenLoc,
1047 RParenLoc, thenStmt, ElseLoc, elseStmt);
1051 struct CaseCompareFunctor {
1052 bool operator()(
const std::pair<llvm::APSInt, CaseStmt*> &LHS,
1053 const llvm::APSInt &RHS) {
1054 return LHS.first < RHS;
1056 bool operator()(
const std::pair<llvm::APSInt, CaseStmt*> &LHS,
1057 const std::pair<llvm::APSInt, CaseStmt*> &RHS) {
1058 return LHS.first < RHS.first;
1060 bool operator()(
const llvm::APSInt &LHS,
1061 const std::pair<llvm::APSInt, CaseStmt*> &RHS) {
1062 return LHS < RHS.first;
1070 const std::pair<llvm::APSInt, CaseStmt*>& rhs) {
1071 if (lhs.first < rhs.first)
1074 if (lhs.first == rhs.first &&
1075 lhs.second->getCaseLoc() < rhs.second->getCaseLoc())
1082static bool CmpEnumVals(
const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,
1083 const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)
1085 return lhs.first < rhs.first;
1090static bool EqEnumVals(
const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,
1091 const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)
1093 return lhs.first == rhs.first;
1099 if (
const auto *FE = dyn_cast<FullExpr>(E))
1100 E = FE->getSubExpr();
1101 while (
const auto *ImpCast = dyn_cast<ImplicitCastExpr>(E)) {
1102 if (ImpCast->getCastKind() != CK_IntegralCast)
break;
1103 E = ImpCast->getSubExpr();
1119 return S.
Diag(Loc, diag::err_typecheck_statement_requires_integer) <<
T;
1124 return S.
Diag(Loc, diag::err_switch_incomplete_class_type)
1125 <<
T <<
Cond->getSourceRange();
1130 return S.
Diag(Loc, diag::err_switch_explicit_conversion) <<
T << ConvTy;
1141 return S.
Diag(Loc, diag::err_switch_multiple_conversions) <<
T;
1152 llvm_unreachable(
"conversion functions are permitted");
1154 } SwitchDiagnoser(
Cond);
1164 if (!
Cond->isTypeDependent() &&
1165 !
Cond->getType()->isIntegralOrEnumerationType())
1176 Expr *CondExpr =
Cond.get().second;
1177 assert((
Cond.isInvalid() || CondExpr) &&
"switch with no condition");
1190 Diag(SwitchLoc, diag::warn_bool_switch_condition)
1198 LParenLoc, RParenLoc);
1204static void AdjustAPSInt(llvm::APSInt &Val,
unsigned BitWidth,
bool IsSigned) {
1205 Val = Val.extOrTrunc(BitWidth);
1206 Val.setIsSigned(IsSigned);
1212 unsigned UnpromotedWidth,
bool UnpromotedSign) {
1220 if (UnpromotedWidth < Val.getBitWidth()) {
1221 llvm::APSInt ConvVal(Val);
1222 AdjustAPSInt(ConvVal, UnpromotedWidth, UnpromotedSign);
1223 AdjustAPSInt(ConvVal, Val.getBitWidth(), Val.isSigned());
1228 S.
Diag(Loc, diag::warn_case_value_overflow) <<
toString(Val, 10)
1239 const Expr *CaseExpr,
1240 EnumValsTy::iterator &EI,
1241 EnumValsTy::iterator &EIEnd,
1242 const llvm::APSInt &Val) {
1248 if (
const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
1257 if (ED->
hasAttr<FlagEnumAttr>())
1260 while (EI != EIEnd && EI->first < Val)
1263 if (EI != EIEnd && EI->first == Val)
1274 const EnumType *CondEnumType = CondType->
getAsCanonical<EnumType>();
1275 const EnumType *CaseEnumType = CaseType->
getAsCanonical<EnumType>();
1276 if (!CondEnumType || !CaseEnumType)
1280 if (!CondEnumType->getOriginalDecl()->getIdentifier() &&
1281 !CondEnumType->getOriginalDecl()->getTypedefNameForAnonDecl())
1283 if (!CaseEnumType->getOriginalDecl()->getIdentifier() &&
1284 !CaseEnumType->getOriginalDecl()->getTypedefNameForAnonDecl())
1290 S.
Diag(Case->
getExprLoc(), diag::warn_comparison_of_mixed_enum_types_switch)
1291 << CondType << CaseType <<
Cond->getSourceRange()
1300 assert(SS ==
getCurFunction()->SwitchStack.back().getPointer() &&
1301 "switch stack missing push/pop!");
1316 SS->
setBody(BodyStmt, SwitchLoc);
1330 const Expr *CondExprBeforePromotion = CondExpr;
1336 bool HasDependentValue
1338 unsigned CondWidth = HasDependentValue ? 0 :
Context.getIntWidth(CondType);
1345 unsigned CondWidthBeforePromotion
1346 = HasDependentValue ? 0 :
Context.getIntWidth(CondTypeBeforePromotion);
1347 bool CondIsSignedBeforePromotion
1354 CaseValsTy CaseVals;
1357 typedef std::vector<std::pair<llvm::APSInt, CaseStmt*> > CaseRangesTy;
1358 CaseRangesTy CaseRanges;
1362 bool CaseListIsErroneous =
false;
1368 SC = SC->getNextSwitchCase()) {
1370 if (
DefaultStmt *DS = dyn_cast<DefaultStmt>(SC)) {
1371 if (TheDefaultStmt) {
1372 Diag(DS->getDefaultLoc(), diag::err_multiple_default_labels_defined);
1379 CaseListIsErroneous =
true;
1381 TheDefaultStmt = DS;
1389 HasDependentValue =
true;
1395 const Expr *LoBeforePromotion = Lo;
1402 CondIsSignedBeforePromotion);
1414 HasDependentValue =
true;
1417 CaseRanges.push_back(std::make_pair(LoVal, CS));
1419 CaseVals.push_back(std::make_pair(LoVal, CS));
1423 if (!HasDependentValue) {
1426 llvm::APSInt ConstantCondValue;
1427 bool HasConstantCond =
false;
1428 if (!TheDefaultStmt) {
1433 ConstantCondValue =
Result.Val.getInt();
1434 assert(!HasConstantCond ||
1435 (ConstantCondValue.getBitWidth() == CondWidth &&
1436 ConstantCondValue.isSigned() == CondIsSigned));
1437 Diag(SwitchLoc, diag::warn_switch_default);
1439 bool ShouldCheckConstantCond = HasConstantCond;
1444 if (!CaseVals.empty()) {
1445 for (
unsigned i = 0, e = CaseVals.size(); i != e; ++i) {
1446 if (ShouldCheckConstantCond &&
1447 CaseVals[i].first == ConstantCondValue)
1448 ShouldCheckConstantCond =
false;
1450 if (i != 0 && CaseVals[i].first == CaseVals[i-1].first) {
1453 StringRef PrevString, CurrString;
1456 if (
DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(PrevCase)) {
1457 PrevString = DeclRef->getDecl()->getName();
1459 if (
DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(CurrCase)) {
1460 CurrString = DeclRef->getDecl()->getName();
1463 CaseVals[i-1].first.toString(CaseValStr);
1465 if (PrevString == CurrString)
1466 Diag(CaseVals[i].second->getLHS()->getBeginLoc(),
1467 diag::err_duplicate_case)
1468 << (PrevString.empty() ? CaseValStr.str() : PrevString);
1470 Diag(CaseVals[i].second->getLHS()->getBeginLoc(),
1471 diag::err_duplicate_case_differing_expr)
1472 << (PrevString.empty() ? CaseValStr.str() : PrevString)
1473 << (CurrString.empty() ? CaseValStr.str() : CurrString)
1476 Diag(CaseVals[i - 1].second->getLHS()->getBeginLoc(),
1477 diag::note_duplicate_case_prev);
1480 CaseListIsErroneous =
true;
1487 if (!CaseRanges.empty()) {
1490 llvm::stable_sort(CaseRanges);
1493 std::vector<llvm::APSInt> HiVals;
1494 for (
unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {
1495 llvm::APSInt &LoVal = CaseRanges[i].first;
1496 CaseStmt *CR = CaseRanges[i].second;
1499 const Expr *HiBeforePromotion = Hi;
1506 CondWidthBeforePromotion, CondIsSignedBeforePromotion);
1512 if (LoVal > HiVal) {
1515 CaseRanges.erase(CaseRanges.begin()+i);
1521 if (ShouldCheckConstantCond &&
1522 LoVal <= ConstantCondValue &&
1523 ConstantCondValue <= HiVal)
1524 ShouldCheckConstantCond =
false;
1526 HiVals.push_back(HiVal);
1532 for (
unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {
1533 llvm::APSInt &CRLo = CaseRanges[i].first;
1534 llvm::APSInt &CRHi = HiVals[i];
1535 CaseStmt *CR = CaseRanges[i].second;
1540 llvm::APSInt OverlapVal(32);
1544 CaseValsTy::iterator I =
1545 llvm::lower_bound(CaseVals, CRLo, CaseCompareFunctor());
1546 if (I != CaseVals.end() && I->first < CRHi) {
1547 OverlapVal = I->first;
1548 OverlapStmt = I->second;
1552 I = std::upper_bound(I, CaseVals.end(), CRHi, CaseCompareFunctor());
1553 if (I != CaseVals.begin() && (I-1)->first >= CRLo) {
1554 OverlapVal = (I-1)->first;
1555 OverlapStmt = (I-1)->second;
1560 if (i && CRLo <= HiVals[i-1]) {
1561 OverlapVal = HiVals[i-1];
1562 OverlapStmt = CaseRanges[i-1].second;
1570 diag::note_duplicate_case_prev);
1573 CaseListIsErroneous =
true;
1579 if (!CaseListIsErroneous && !CaseListIsIncomplete &&
1580 ShouldCheckConstantCond) {
1583 Diag(CondExpr->
getExprLoc(), diag::warn_missing_case_for_condition)
1594 if (!CaseListIsErroneous && !CaseListIsIncomplete && !HasConstantCond &&
1597 if (!ED->isCompleteDefinition() || ED->enumerators().empty())
1604 for (
auto *EDI : ED->enumerators()) {
1605 llvm::APSInt Val = EDI->getInitVal();
1607 EnumVals.push_back(std::make_pair(Val, EDI));
1610 auto EI = EnumVals.begin(), EIEnd = llvm::unique(EnumVals,
EqEnumVals);
1613 for (CaseValsTy::const_iterator CI = CaseVals.begin();
1614 CI != CaseVals.end(); CI++) {
1615 Expr *CaseExpr = CI->second->getLHS();
1619 << CondTypeBeforePromotion;
1623 EI = EnumVals.begin();
1624 for (CaseRangesTy::const_iterator RI = CaseRanges.begin();
1625 RI != CaseRanges.end(); RI++) {
1626 Expr *CaseExpr = RI->second->getLHS();
1630 << CondTypeBeforePromotion;
1633 RI->second->getRHS()->EvaluateKnownConstInt(
Context);
1636 CaseExpr = RI->second->getRHS();
1640 << CondTypeBeforePromotion;
1644 auto CI = CaseVals.begin();
1645 auto RI = CaseRanges.begin();
1646 bool hasCasesNotInSwitch =
false;
1650 for (EI = EnumVals.begin(); EI != EIEnd; EI++) {
1652 switch (EI->second->getAvailability()) {
1669 if (EI->second->hasAttr<UnusedAttr>())
1673 while (CI != CaseVals.end() && CI->first < EI->first)
1676 if (CI != CaseVals.end() && CI->first == EI->first)
1680 for (; RI != CaseRanges.end(); RI++) {
1682 RI->second->getRHS()->EvaluateKnownConstInt(
Context);
1684 if (EI->first <= Hi)
1688 if (RI == CaseRanges.end() || EI->first < RI->first) {
1689 hasCasesNotInSwitch =
true;
1690 UnhandledNames.push_back(EI->second->getDeclName());
1694 if (TheDefaultStmt && UnhandledNames.empty() && ED->isClosedNonFlag())
1698 if (!UnhandledNames.empty()) {
1700 ? diag::warn_def_missing_case
1701 : diag::warn_missing_case)
1704 for (
size_t I = 0, E = std::min(UnhandledNames.size(), (
size_t)3);
1706 DB << UnhandledNames[I];
1709 if (!hasCasesNotInSwitch)
1717 diag::warn_empty_switch_body);
1721 if (CaseListIsErroneous)
1735 Context.hasSameUnqualifiedType(SrcType, DstType))
1742 if (!ED->isClosed())
1745 if (
Diags.isIgnored(diag::warn_not_in_enum_assignment, SrcExpr->
getExprLoc()))
1753 unsigned DstWidth =
Context.getIntWidth(DstType);
1757 if (ED->hasAttr<FlagEnumAttr>()) {
1770 for (
auto *EDI : ED->enumerators()) {
1771 llvm::APSInt Val = EDI->getInitVal();
1773 EnumVals.emplace_back(Val, EDI);
1775 if (EnumVals.empty())
1778 EnumValsTy::iterator EIend = llvm::unique(EnumVals,
EqEnumVals);
1781 EnumValsTy::const_iterator EI = EnumVals.begin();
1782 while (EI != EIend && EI->first < *RHSVal)
1784 if (EI == EIend || EI->first != *RHSVal) {
1793 if (
Cond.isInvalid())
1796 auto CondVal =
Cond.get();
1797 CheckBreakContinueBinding(CondVal.second);
1799 if (CondVal.second &&
1800 !
Diags.isIgnored(diag::warn_comma_operator, CondVal.second->getExprLoc()))
1801 CommaVisitor(*this).Visit(CondVal.second);
1816 WhileLoc, LParenLoc, RParenLoc);
1823 assert(
Cond &&
"ActOnDoStmt(): missing expression");
1825 CheckBreakContinueBinding(
Cond);
1838 !
Diags.isIgnored(diag::warn_comma_operator,
Cond->getExprLoc()))
1839 CommaVisitor(*this).Visit(
Cond);
1861 DeclSetVector &Decls;
1867 DeclExtractor(
Sema &S, DeclSetVector &Decls,
1869 Inherited(S.Context),
1874 bool isSimple() {
return Simple; }
1877 void VisitMemberExpr(MemberExpr* E) {
1883 void VisitStmt(Stmt *S) { Simple =
false; }
1885 void VisitBinaryOperator(BinaryOperator *E) {
1894 void VisitUnaryOperator(UnaryOperator *E) {
1902 void VisitConditionalOperator(ConditionalOperator *E) {
1908 void VisitParenExpr(ParenExpr *E) {
1912 void VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
1917 void VisitIntegerLiteral(IntegerLiteral *E) { }
1918 void VisitFloatingLiteral(FloatingLiteral *E) { }
1919 void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) { }
1920 void VisitCharacterLiteral(CharacterLiteral *E) { }
1921 void VisitGNUNullExpr(GNUNullExpr *E) { }
1922 void VisitImaginaryLiteral(ImaginaryLiteral *E) { }
1924 void VisitDeclRefExpr(DeclRefExpr *E) {
1925 VarDecl *VD = dyn_cast<VarDecl>(E->
getDecl());
1942 DeclSetVector &Decls;
1946 typedef EvaluatedExprVisitor<DeclMatcher> Inherited;
1948 DeclMatcher(Sema &S, DeclSetVector &Decls, Stmt *Statement) :
1949 Inherited(S.Context), Decls(Decls), FoundDecl(
false) {
1950 if (!Statement)
return;
1955 void VisitReturnStmt(ReturnStmt *S) {
1959 void VisitBreakStmt(BreakStmt *S) {
1963 void VisitGotoStmt(GotoStmt *S) {
1974 void CheckLValueToRValueCast(Expr *E) {
1981 if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) {
1982 Visit(CO->getCond());
1983 CheckLValueToRValueCast(CO->getTrueExpr());
1984 CheckLValueToRValueCast(CO->getFalseExpr());
1988 if (BinaryConditionalOperator *BCO =
1989 dyn_cast<BinaryConditionalOperator>(E)) {
1990 CheckLValueToRValueCast(BCO->getOpaqueValue()->getSourceExpr());
1991 CheckLValueToRValueCast(BCO->getFalseExpr());
1998 void VisitDeclRefExpr(DeclRefExpr *E) {
1999 if (VarDecl *VD = dyn_cast<VarDecl>(E->
getDecl()))
2000 if (Decls.count(VD))
2004 void VisitPseudoObjectExpr(PseudoObjectExpr *POE) {
2008 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(S))
2010 Visit(OVE->getSourceExpr());
2016 bool FoundDeclInUse() {
return FoundDecl; }
2020 void CheckForLoopConditionalStatement(
Sema &S,
Expr *Second,
2023 if (!Second)
return;
2030 DeclSetVector Decls;
2032 DeclExtractor DE(S, Decls, Ranges);
2036 if (!DE.isSimple())
return;
2039 if (Decls.size() == 0)
return;
2042 for (
auto *VD : Decls)
2046 if (DeclMatcher(S, Decls, Second).FoundDeclInUse() ||
2047 DeclMatcher(S, Decls, Third).FoundDeclInUse() ||
2048 DeclMatcher(S, Decls, Body).FoundDeclInUse())
2052 if (Decls.size() > 4) {
2055 PDiag << (unsigned)Decls.size();
2056 for (
auto *VD : Decls)
2060 for (
auto Range : Ranges)
2063 S.
Diag(Ranges.begin()->getBegin(), PDiag);
2068 bool ProcessIterationStmt(
Sema &S,
Stmt* Statement,
bool &Increment,
2070 if (
auto Cleanups = dyn_cast<ExprWithCleanups>(Statement))
2071 if (!Cleanups->cleanupsHaveSideEffects())
2074 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(Statement)) {
2075 switch (UO->getOpcode()) {
2076 default:
return false;
2086 DRE = dyn_cast<DeclRefExpr>(UO->getSubExpr());
2094 default:
return false;
2102 DRE = dyn_cast<DeclRefExpr>(
Call->getArg(0));
2112 SourceLocation BreakLoc;
2113 SourceLocation ContinueLoc;
2114 bool InSwitch =
false;
2117 BreakContinueFinder(Sema &S,
const Stmt* Body) :
2118 Inherited(S.Context) {
2122 typedef ConstEvaluatedExprVisitor<BreakContinueFinder> Inherited;
2124 void VisitContinueStmt(
const ContinueStmt* E) {
2128 void VisitBreakStmt(
const BreakStmt* E) {
2133 void VisitSwitchStmt(
const SwitchStmt* S) {
2143 if (
const Stmt *Body = S->
getBody())
2148 void VisitForStmt(
const ForStmt *S) {
2155 void VisitWhileStmt(
const WhileStmt *) {
2160 void VisitDoStmt(
const DoStmt *) {
2165 void VisitCXXForRangeStmt(
const CXXForRangeStmt *S) {
2178 void VisitObjCForCollectionStmt(
const ObjCForCollectionStmt *S) {
2187 bool ContinueFound() {
return ContinueLoc.
isValid(); }
2188 bool BreakFound() {
return BreakLoc.
isValid(); }
2189 SourceLocation GetContinueLoc() {
return ContinueLoc; }
2190 SourceLocation GetBreakLoc() {
return BreakLoc; }
2199 void CheckForRedundantIteration(
Sema &S,
Expr *Third,
Stmt *Body) {
2201 if (!Body || !Third)
return;
2207 if (!LastStmt)
return;
2213 bool LoopIncrement, LastIncrement;
2216 if (!ProcessIterationStmt(S, Third, LoopIncrement, LoopDRE))
return;
2217 if (!ProcessIterationStmt(S, LastStmt, LastIncrement, LastDRE))
return;
2221 if (LoopIncrement != LastIncrement ||
2224 if (BreakContinueFinder(S, Body).ContinueFound())
return;
2227 << LastDRE->
getDecl() << LastIncrement;
2235void Sema::CheckBreakContinueBinding(
Expr *E) {
2238 BreakContinueFinder BCFinder(*
this, E);
2239 Scope *BreakParent = CurScope->getBreakParent();
2240 if (BCFinder.BreakFound() && BreakParent) {
2242 Diag(BCFinder.GetBreakLoc(), diag::warn_break_binds_to_switch);
2244 Diag(BCFinder.GetBreakLoc(), diag::warn_loop_ctrl_binds_to_inner)
2247 }
else if (BCFinder.ContinueFound() && CurScope->getContinueParent()) {
2248 Diag(BCFinder.GetContinueLoc(), diag::warn_loop_ctrl_binds_to_inner)
2265 const Decl *NonVarSeen =
nullptr;
2266 bool VarDeclSeen =
false;
2267 for (
auto *DI : DS->decls()) {
2268 if (
VarDecl *VD = dyn_cast<VarDecl>(DI)) {
2271 Diag(DI->getLocation(),
2273 ? diag::warn_c17_non_local_variable_decl_in_for
2274 : diag::ext_c23_non_local_variable_decl_in_for);
2275 }
else if (!NonVarSeen) {
2289 if (NonVarSeen && !VarDeclSeen)
2292 : diag::ext_c23_non_variable_decl_in_for);
2296 CheckBreakContinueBinding(Second.
get().second);
2297 CheckBreakContinueBinding(third.
get());
2299 if (!Second.
get().first)
2300 CheckForLoopConditionalStatement(*
this, Second.
get().second, third.
get(),
2302 CheckForRedundantIteration(*
this, third.
get(), Body);
2304 if (Second.
get().second &&
2305 !
Diags.isIgnored(diag::warn_comma_operator,
2306 Second.
get().second->getExprLoc()))
2307 CommaVisitor(*this).Visit(Second.
get().second);
2315 Body, ForLoc, LParenLoc, RParenLoc);
2335 if (
Decl->getType()->isUndeducedType()) {
2348 SemaRef.
Diag(Loc, DiagID) <<
Init->getType();
2352 Decl->getTypeSourceInfo()->getTypeLoc(),
Init, InitType, Info);
2355 SemaRef.
Diag(Loc, DiagID) <<
Init->getType();
2362 Decl->setType(InitType);
2380enum BeginEndFunction {
2389void NoteForRangeBeginEndFunction(
Sema &SemaRef,
Expr *E,
2390 BeginEndFunction BEF) {
2391 CallExpr *CE = dyn_cast<CallExpr>(E);
2399 std::string Description;
2400 bool IsTemplate =
false;
2407 SemaRef.
Diag(Loc, diag::note_for_range_begin_end)
2408 << BEF << IsTemplate << Description << E->
getType();
2420 Decl->setCXXForRangeImplicitVar(
true);
2443 return Diag(InitStmt->
getBeginLoc(), diag::err_objc_for_range_init_stmt)
2449 assert(DS &&
"first part of for range not a decl stmt");
2476 const auto DepthStr = std::to_string(S->
getDepth() / 2);
2478 VarDecl *RangeVar = BuildForRangeVarDecl(*
this, RangeLoc,
2479 Context.getAutoRRefDeductType(),
2480 std::string(
"__range") + DepthStr);
2482 diag::err_for_range_deduction_failure)) {
2497 ForLoc, CoawaitLoc, InitStmt, ColonLoc, RangeDecl.
get(),
2499 nullptr,
nullptr, DS, RParenLoc, Kind,
2500 LifetimeExtendTemps);
2523 ExprResult *EndExpr, BeginEndFunction *BEF) {
2533 auto BuildBegin = [&] {
2537 BeginMemberLookup, CandidateSet,
2538 BeginRange, BeginExpr);
2543 << ColonLoc << BEF_begin << BeginRange->
getType();
2556 diag::err_for_range_iter_deduction_failure)) {
2557 NoteForRangeBeginEndFunction(SemaRef, BeginExpr->
get(), *BEF);
2563 auto BuildEnd = [&] {
2567 EndMemberLookup, CandidateSet,
2572 << ColonLoc << BEF_end << EndRange->
getType();
2576 diag::err_for_range_iter_deduction_failure)) {
2577 NoteForRangeBeginEndFunction(SemaRef, EndExpr->
get(), *BEF);
2597 if (BeginMemberLookup.
empty() != EndMemberLookup.
empty()) {
2602 auto BuildNonmember = [&](
2612 switch (BuildFound()) {
2619 SemaRef.
PDiag(diag::err_for_range_invalid)
2620 << BeginRange->
getType() << BEFFound),
2627 diag::note_for_range_member_begin_end_ignored)
2628 << BeginRange->
getType() << BEFFound;
2632 llvm_unreachable(
"unexpected ForRangeStatus");
2634 if (BeginMemberLookup.
empty())
2635 return BuildNonmember(BEF_end, EndMemberLookup, BuildEnd, BuildBegin);
2636 return BuildNonmember(BEF_begin, BeginMemberLookup, BuildBegin, BuildEnd);
2668 AdjustedRange = SemaRef.
BuildUnaryOp(S, RangeLoc, UO_Deref, Range);
2673 S, ForLoc, CoawaitLoc, InitStmt, LoopVarDecl, ColonLoc,
2682 SemaRef.
Diag(RangeLoc, diag::err_for_range_dereference)
2685 S, ForLoc, CoawaitLoc, InitStmt, LoopVarDecl, ColonLoc,
2724 if (
auto *DD = dyn_cast<DecompositionDecl>(LoopVar))
2725 for (
auto *Binding : DD->bindings()) {
2726 if (!Binding->isParameterPack())
2727 Binding->setType(
Context.DependentTy);
2731 }
else if (!BeginDeclStmt.
get()) {
2750 QualType RangeType = Range->getType();
2753 diag::err_for_range_incomplete_type))
2760 for (
auto *MTE : LifetimeExtendTemps)
2766 const auto DepthStr = std::to_string(S->
getDepth() / 2);
2767 VarDecl *BeginVar = BuildForRangeVarDecl(*
this, ColonLoc, AutoType,
2768 std::string(
"__begin") + DepthStr);
2769 VarDecl *EndVar = BuildForRangeVarDecl(*
this, ColonLoc, AutoType,
2770 std::string(
"__end") + DepthStr);
2781 BeginExpr = BeginRangeRef;
2788 diag::err_for_range_iter_deduction_failure)) {
2789 NoteForRangeBeginEndFunction(*
this, BeginExpr.
get(), BEF_begin);
2797 Context, CAT->getSize(),
Context.getPointerDiffType(), RangeLoc);
2799 dyn_cast<VariableArrayType>(UnqAT)) {
2826 VAT->desugar(), RangeLoc))
2836 Context.getTrivialTypeSourceInfo(
2837 VAT->getElementType(), RangeLoc))
2845 SizeOfVLAExprR.
get(), SizeOfEachElementExprR.
get());
2852 llvm_unreachable(
"Unexpected array type in for-range");
2856 EndExpr =
ActOnBinOp(S, ColonLoc, tok::plus, EndRangeRef.
get(),
2861 diag::err_for_range_iter_deduction_failure)) {
2862 NoteForRangeBeginEndFunction(*
this, EndExpr.
get(), BEF_end);
2868 BeginEndFunction BEFFailure;
2870 *
this, BeginRangeRef.
get(), EndRangeRef.
get(), RangeType, BeginVar,
2871 EndVar, ColonLoc, CoawaitLoc, &CandidateSet, &BeginExpr, &EndExpr,
2875 BEFFailure == BEF_begin) {
2878 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Range)) {
2880 QualType ArrayTy = PVD->getOriginalType();
2881 QualType PointerTy = PVD->getType();
2883 Diag(Range->getBeginLoc(), diag::err_range_on_array_parameter)
2884 << RangeLoc << PVD << ArrayTy << PointerTy;
2885 Diag(PVD->getLocation(), diag::note_declared_at);
2894 CoawaitLoc, InitStmt,
2895 LoopVarDecl, ColonLoc,
2904 Expr *Range = BEFFailure ? EndRangeRef.
get() : BeginRangeRef.
get();
2907 PDiag(diag::err_for_range_invalid)
2908 << RangeLoc << Range->getType()
2918 "invalid range expression in for loop");
2923 if (!
Context.hasSameType(BeginType, EndType)) {
2925 ? diag::warn_for_range_begin_end_types_differ
2926 : diag::ext_for_range_begin_end_types_differ)
2927 << BeginType << EndType;
2928 NoteForRangeBeginEndFunction(*
this, BeginExpr.
get(), BEF_begin);
2929 NoteForRangeBeginEndFunction(*
this, EndExpr.
get(), BEF_end);
2949 NotEqExpr =
ActOnBinOp(S, ColonLoc, tok::exclaimequal,
2950 BeginRef.
get(), EndRef.
get());
2957 Diag(RangeLoc, diag::note_for_range_invalid_iterator)
2958 << RangeLoc << 0 << BeginRangeRef.
get()->
getType();
2959 NoteForRangeBeginEndFunction(*
this, BeginExpr.
get(), BEF_begin);
2960 if (!
Context.hasSameType(BeginType, EndType))
2961 NoteForRangeBeginEndFunction(*
this, EndExpr.
get(), BEF_end);
2972 if (!IncrExpr.isInvalid() && CoawaitLoc.
isValid())
2977 if (!IncrExpr.isInvalid())
2979 if (IncrExpr.isInvalid()) {
2980 Diag(RangeLoc, diag::note_for_range_invalid_iterator)
2981 << RangeLoc << 2 << BeginRangeRef.
get()->
getType() ;
2982 NoteForRangeBeginEndFunction(*
this, BeginExpr.
get(), BEF_begin);
2994 Diag(RangeLoc, diag::note_for_range_invalid_iterator)
2995 << RangeLoc << 1 << BeginRangeRef.
get()->
getType();
2996 NoteForRangeBeginEndFunction(*
this, BeginExpr.
get(), BEF_begin);
3006 NoteForRangeBeginEndFunction(*
this, BeginExpr.
get(), BEF_begin);
3021 InitStmt, RangeDS, cast_or_null<DeclStmt>(BeginDeclStmt.
get()),
3022 cast_or_null<DeclStmt>(EndDeclStmt.
get()), NotEqExpr.
get(),
3023 IncrExpr.get(), LoopVarDS,
nullptr, ForLoc, CoawaitLoc,
3024 ColonLoc, RParenLoc);
3043 if (
auto Cleanups = dyn_cast<ExprWithCleanups>(InitExpr))
3044 if (!Cleanups->cleanupsHaveSideEffects())
3045 InitExpr = Cleanups->getSubExpr();
3048 dyn_cast<MaterializeTemporaryExpr>(InitExpr);
3079 ReferenceReturnType = ReturnType;
3082 if (!ReferenceReturnType.
isNull()) {
3087 diag::warn_for_range_const_ref_binds_temp_built_from_ref)
3088 << VD << VariableType << ReferenceReturnType;
3101 SemaRef.
Diag(VD->
getLocation(), diag::warn_for_range_ref_binds_ret_temp)
3102 << VD << RangeInitType;
3115 return RD->hasAttr<TrivialABIAttr>();
3132 if (!CE->getConstructor()->isCopyConstructor())
3134 }
else if (
const CastExpr *CE = dyn_cast<CastExpr>(InitExpr)) {
3135 if (CE->getCastKind() != CK_LValueToRValue)
3153 << VD << VariableType;
3175 diag::warn_for_range_const_ref_binds_temp_built_from_ref, Loc) &&
3176 SemaRef.
Diags.
isIgnored(diag::warn_for_range_ref_binds_ret_temp, Loc) &&
3199 ForStmt->getRangeInit()->getType());
3216 diag::warn_empty_range_based_for_body);
3230 if (
getCurScope()->isInOpenACCComputeConstructScope())
3264 if (
getCurScope()->isInOpenACCComputeConstructScope())
3271 const Scope &DestScope) {
3274 S.
Diag(Loc, diag::warn_jump_out_of_seh_finally);
3283 assert(
Target &&
"not a named break/continue?");
3290 S.
Diag(KWLoc, diag::err_acc_branch_in_out_compute_construct)
3303 if (IsContinue && !
Found->isContinueScope()) {
3304 S.
Diag(LabelLoc, diag::err_continue_switch);
3310 S.
Diag(LabelLoc, diag::err_break_continue_label_not_found) << IsContinue;
3329 return StmtError(
Diag(ContinueLoc, diag::err_continue_not_in_loop));
3335 return StmtError(
Diag(ContinueLoc, diag::err_continue_from_cond_var_init));
3343 Diag(ContinueLoc, diag::err_acc_branch_in_out_compute_construct)
3366 return StmtError(
Diag(BreakLoc, diag::err_break_not_in_loop_or_switch));
3370 return StmtError(
Diag(BreakLoc, diag::err_omp_loop_cannot_use_stmt)
3384 Diag(BreakLoc, diag::err_acc_branch_in_out_compute_construct)
3398 const auto *DR = dyn_cast<DeclRefExpr>(E->
IgnoreParens());
3399 if (!DR || DR->refersToEnclosingVariableOrCapture())
3401 const auto *VD = dyn_cast<VarDecl>(DR->getDecl());
3424 if (VD->
getKind() == Decl::ParmVar)
3426 else if (VD->
getKind() != Decl::Var)
3439 if (VD->
hasAttr<BlocksAttr>())
3475 auto invalidNRVO = [&] {
3484 if ((ReturnType->
getTypeClass() == Type::TypeClass::Auto &&
3487 return invalidNRVO();
3493 return invalidNRVO();
3499 !
Context.hasSameUnqualifiedType(ReturnType, VDType))
3513 const auto *Step = llvm::find_if(
Seq.steps(), [](
const auto &Step) {
3514 return Step.Kind == InitializationSequence::SK_ConstructorInitialization ||
3515 Step.Kind == InitializationSequence::SK_UserConversion;
3517 if (Step !=
Seq.step_end()) {
3518 const auto *FD = Step->Function.Function;
3529 bool SupressSimplerImplicitMoves) {
3535 Expr *InitExpr = &AsRvalue;
3537 Value->getBeginLoc());
3539 auto Res =
Seq.getFailedOverloadResult();
3550 return Seq.Perform(*
this, Entity, Kind,
Value);
3570 bool SupressSimplerImplicitMoves) {
3578 bool HasDeducedReturnType =
3588 RetValExp = ER.
get();
3594 if (HasDeducedReturnType) {
3607 assert(AT &&
"lost auto type from lambda return type");
3623 RetValExp =
Result.get();
3638 Diag(ReturnLoc, diag::err_lambda_return_init_list)
3652 if (
auto *CurBlock = dyn_cast<BlockScopeInfo>(CurCap)) {
3654 Diag(ReturnLoc, diag::err_noreturn_has_return_expr)
3655 << diag::FalloffFunctionKind::Block;
3658 }
else if (
auto *CurRegion = dyn_cast<CapturedRegionScopeInfo>(CurCap)) {
3659 Diag(ReturnLoc, diag::err_return_in_captured_stmt) << CurRegion->getRegionName();
3662 assert(CurLambda &&
"unknown kind of captured scope");
3666 Diag(ReturnLoc, diag::err_noreturn_has_return_expr)
3667 << diag::FalloffFunctionKind::Lambda;
3685 Diag(ReturnLoc, diag::ext_return_has_void_expr) <<
"literal" << 2;
3687 Diag(ReturnLoc, diag::err_return_block_has_expr);
3688 RetValExp =
nullptr;
3691 }
else if (!RetValExp) {
3692 return StmtError(
Diag(ReturnLoc, diag::err_block_return_missing_expr));
3705 Entity, NRInfo, RetValExp, SupressSimplerImplicitMoves);
3710 RetValExp = Res.
get();
3711 CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc);
3719 RetValExp = ER.
get();
3733 if (
auto *CurBlock = dyn_cast<BlockScopeInfo>(CurCap);
3736 CurBlock->TheDecl->setInvalidDecl();
3756 LocalTypedefNameReferencer(
Sema &S) : S(S) {}
3757 bool VisitRecordType(RecordType *RT)
override;
3762bool LocalTypedefNameReferencer::VisitRecordType(RecordType *RT) {
3763 auto *R = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl());
3764 if (!R || !R->isLocalClass() || !R->isLocalClass()->isExternallyVisible() ||
3765 R->isDependentType())
3767 for (
auto *TmpD : R->decls())
3768 if (
auto *
T = dyn_cast<TypedefNameDecl>(TmpD))
3769 if (
T->getAccess() !=
AS_private || R->hasFriends())
3784 Expr *RetExpr,
const AutoType *AT) {
3791 if (isa_and_nonnull<InitListExpr>(RetExpr)) {
3796 : diag::err_auto_fn_return_init_list)
3806 assert(AT->isDeduced() &&
"should have deduced to dependent type");
3820 Diag(ReturnLoc, diag::err_auto_fn_return_void_but_not_auto)
3827 QualType Deduced = AT->getDeducedType();
3836 if (FindResult.Expression)
3837 TemplateSpecLoc = FindResult.Expression->getNameLoc();
3841 OrigResultType, RetExpr, Deduced, Info,
false,
3857 Diag(ReturnLoc, diag::err_typecheck_missing_return_type_incompatible)
3860 Diag(ReturnLoc, diag::err_auto_fn_different_deductions)
3861 << (AT->isDecltypeAuto() ? 1 : 0) << Info.
SecondArg
3875 LocalTypedefNameReferencer(*this).TraverseType(RetExpr->
getType());
3885 if (!FD->
isInvalidDecl() && AT->getDeducedType() != Deduced)
3887 Context.adjustDeducedFunctionResultType(FD, Deduced);
3899 if (
getCurScope()->isInOpenACCComputeConstructScope())
3901 Diag(ReturnLoc, diag::err_acc_branch_in_out_compute_construct)
3908 "first coroutine location not set");
3909 Diag(ReturnLoc, diag::err_return_in_coroutine);
3914 CheckInvalidBuiltinCountedByRef(RetVal.
get(),
3925 CurScope->updateNRVOCandidate(VD);
3947 bool AllowRecovery) {
3955 bool SupressSimplerImplicitMoves =
3963 SupressSimplerImplicitMoves);
3967 const AttrVec *Attrs =
nullptr;
3968 bool isObjCMethod =
false;
3975 Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr) << FD;
3976 if (FD->
isMain() && RetValExp)
3978 Diag(ReturnLoc, diag::warn_main_returns_bool_literal)
3980 if (FD->
hasAttr<CmseNSEntryAttr>() && RetValExp) {
3982 if (RT->getOriginalDecl()->isOrContainsUnion())
3987 FnRetType = MD->getReturnType();
3988 isObjCMethod =
true;
3990 Attrs = &MD->getAttrs();
3991 if (MD->hasRelatedResultType() && MD->getClassInterface()) {
3995 RelatedRetType =
Context.getObjCInterfaceType(MD->getClassInterface());
3996 RelatedRetType =
Context.getObjCObjectPointerType(RelatedRetType);
4002 const auto *ATy = dyn_cast<ArrayType>(RetValExp->
getType());
4003 if (ATy && ATy->getElementType().isWebAssemblyReferenceType()) {
4004 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
4018 RetValExp = ER.
get();
4044 AT->isDeduced() ? FnRetType :
QualType());
4045 if (Recovery.isInvalid())
4047 RetValExp = Recovery.get();
4063 if (
auto *ILE = dyn_cast<InitListExpr>(RetValExp)) {
4068 int FunctionKind = 0;
4076 Diag(ReturnLoc, diag::err_return_init_list)
4080 RetValExp = AllowRecovery
4082 ILE->getRBraceLoc(), ILE->inits())
4087 unsigned D = diag::ext_return_has_expr;
4092 D = diag::err_ctor_dtor_returns_void;
4094 D = diag::ext_return_has_void_expr;
4101 RetValExp =
Result.get();
4106 if (D == diag::err_ctor_dtor_returns_void) {
4108 Diag(ReturnLoc, D) << CurDecl << isa<CXXDestructorDecl>(CurDecl)
4112 else if (D != diag::ext_return_has_void_expr ||
4116 int FunctionKind = 0;
4134 RetValExp = ER.
get();
4140 }
else if (!RetValExp && !HasDependentReturnType) {
4147 Diag(ReturnLoc, diag::err_constexpr_return_missing_expr)
4153 unsigned DiagID =
getLangOpts().C99 ? diag::ext_return_missing_expr
4154 : diag::warn_return_missing_expr;
4158 "Not in a FunctionDecl or ObjCMethodDecl?");
4159 bool IsMethod = FD ==
nullptr;
4162 Diag(ReturnLoc, DiagID) << ND << IsMethod;
4168 assert(RetValExp || HasDependentReturnType);
4169 QualType RetType = RelatedRetType.
isNull() ? FnRetType : RelatedRetType;
4182 Entity, NRInfo, RetValExp, SupressSimplerImplicitMoves);
4185 RetValExp->
getEndLoc(), RetValExp, RetType);
4196 if (!RelatedRetType.
isNull()) {
4207 CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc, isObjCMethod, Attrs,
4216 RetValExp = ER.
get();
4223 if (
Result->getNRVOCandidate())
4234 Stmt *HandlerBlock) {
4237 CXXCatchStmt(CatchLoc, cast_or_null<VarDecl>(ExDecl), HandlerBlock);
4241class CatchHandlerType {
4243 LLVM_PREFERRED_TYPE(
bool)
4244 unsigned IsPointer : 1;
4248 friend struct llvm::DenseMapInfo<CatchHandlerType>;
4249 enum Unique { ForDenseMap };
4250 CatchHandlerType(
QualType QT, Unique) : QT(QT), IsPointer(
false) {}
4256 CatchHandlerType(QualType Q) : QT(Q), IsPointer(
false) {
4268 CatchHandlerType(QualType QT,
bool IsPointer)
4269 : QT(QT), IsPointer(IsPointer) {}
4271 QualType underlying()
const {
return QT; }
4272 bool isPointer()
const {
return IsPointer; }
4274 friend bool operator==(
const CatchHandlerType &LHS,
4275 const CatchHandlerType &RHS) {
4277 if (LHS.IsPointer != RHS.IsPointer)
4280 return LHS.QT == RHS.QT;
4286template <>
struct DenseMapInfo<CatchHandlerType> {
4288 return CatchHandlerType(DenseMapInfo<QualType>::getEmptyKey(),
4289 CatchHandlerType::ForDenseMap);
4293 return CatchHandlerType(DenseMapInfo<QualType>::getTombstoneKey(),
4294 CatchHandlerType::ForDenseMap);
4298 return DenseMapInfo<QualType>::getHashValue(
Base.underlying());
4302 const CatchHandlerType &RHS) {
4309class CatchTypePublicBases {
4310 const llvm::DenseMap<QualType, CXXCatchStmt *> &TypesToCheck;
4312 CXXCatchStmt *FoundHandler;
4313 QualType FoundHandlerType;
4314 QualType TestAgainstType;
4317 CatchTypePublicBases(
const llvm::DenseMap<QualType, CXXCatchStmt *> &
T,
4319 : TypesToCheck(
T), FoundHandler(
nullptr), TestAgainstType(QT) {}
4321 CXXCatchStmt *getFoundHandler()
const {
return FoundHandler; }
4322 QualType getFoundHandlerType()
const {
return FoundHandlerType; }
4324 bool operator()(
const CXXBaseSpecifier *S, CXXBasePath &) {
4327 const auto &M = TypesToCheck;
4328 auto I = M.find(Check);
4340 if (I->second->getCaughtType()->isPointerType() ==
4342 FoundHandler = I->second;
4343 FoundHandlerType = Check;
4355 const llvm::Triple &
T =
Context.getTargetInfo().getTriple();
4356 const bool IsOpenMPGPUTarget =
4357 getLangOpts().OpenMPIsTargetDevice && (
T.isNVPTX() ||
T.isAMDGCN());
4363 if (IsOpenMPGPUTarget)
4364 targetDiag(TryLoc, diag::warn_try_not_valid_on_target) <<
T.str();
4372 Diag(TryLoc, diag::err_omp_simd_region_cannot_use_stmt) <<
"try";
4378 Diag(TryLoc, diag::err_mixing_cxx_try_seh_try) << 0;
4382 const unsigned NumHandlers = Handlers.size();
4383 assert(!Handlers.empty() &&
4384 "The parser shouldn't call this if there are no handlers.");
4386 llvm::DenseMap<QualType, CXXCatchStmt *> HandledBaseTypes;
4387 llvm::DenseMap<CatchHandlerType, CXXCatchStmt *> HandledTypes;
4388 for (
unsigned i = 0; i < NumHandlers; ++i) {
4395 if (i < NumHandlers - 1)
4409 QualType Underlying = HandlerCHT.underlying();
4411 if (!RD->hasDefinition())
4420 CatchTypePublicBases CTPB(HandledBaseTypes,
4422 if (RD->lookupInBases(CTPB, Paths)) {
4427 diag::warn_exception_caught_by_earlier_handler)
4430 diag::note_previous_exception_handler)
4442 auto R = HandledTypes.insert(
4447 diag::warn_exception_caught_by_earlier_handler)
4450 diag::note_previous_exception_handler)
4462 const llvm::Triple &
T =
Context.getTargetInfo().getTriple();
4463 const bool IsOpenMPGPUTarget =
4464 getLangOpts().OpenMPIsTargetDevice && (
T.isNVPTX() ||
T.isAMDGCN());
4475 targetDiag(Loc, diag::err_exceptions_disabled) << (IsTry ?
"try" :
"throw");
4480 assert(TryBlock && Handler);
4507 Diag(TryLoc, diag::err_seh_try_outside_functions);
4510 if (!
Context.getTargetInfo().isSEHTrySupported())
4511 Diag(TryLoc, diag::err_seh_try_unsupported);
4518 assert(FilterExpr &&
Block);
4522 Diag(FilterExpr->
getExprLoc(), diag::err_filter_expression_integral)
4544 Scope *SEHTryParent = CurScope;
4546 SEHTryParent = SEHTryParent->
getParent();
4548 return StmtError(
Diag(Loc, diag::err_ms___leave_not_in___try));
4561 QualifierLoc, NameInfo,
4579 unsigned NumParams) {
4597 assert(NumParams > 0 &&
"CapturedStmt requires context parameter");
4641 CaptureInits.push_back(
Init.get());
4646static std::optional<int>
4663 unsigned NumParams) {
4665 Diag(Loc, diag::err_sme_openmp_captured_region) << *ErrorIndex;
4698 unsigned OpenMPCaptureLevel) {
4700 Diag(Loc, diag::err_sme_openmp_captured_region) << *ErrorIndex;
4707 bool ContextIsFound =
false;
4708 unsigned ParamNum = 0;
4711 I != E; ++I, ++ParamNum) {
4712 if (I->second.isNull()) {
4713 assert(!ContextIsFound &&
4714 "null type has been found already for '__context' parameter");
4725 ContextIsFound =
true;
4735 assert(ContextIsFound &&
"no null type for '__context' parameter");
4736 if (!ContextIsFound) {
4767 Record->setInvalidDecl();
4793 Captures, CaptureInits, CD, RD);
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines the clang::Expr interface and subclasses for C++ expressions.
llvm::MachO::Target Target
llvm::MachO::Record Record
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file declares semantic analysis for CUDA constructs.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenMP constructs and clauses.
static bool CmpEnumVals(const std::pair< llvm::APSInt, EnumConstantDecl * > &lhs, const std::pair< llvm::APSInt, EnumConstantDecl * > &rhs)
CmpEnumVals - Comparison predicate for sorting enumeration values.
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 Scope * FindLabeledBreakContinueScope(Sema &S, Scope *CurScope, SourceLocation KWLoc, LabelDecl *Target, SourceLocation LabelLoc, bool IsContinue)
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 std::optional< int > isOpenMPCapturedRegionInArmSMEFunction(Sema const &S, CapturedRegionKind Kind)
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.
Defines the clang::TypeLoc interface and its subclasses.
Allows QualTypes to be sorted and hence used in maps and sets.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
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.
CanQualType getCanonicalTagType(const TagDecl *TD) const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Attr - This represents one attribute.
SourceLocation getLocation() const
SourceRange getRange() const
static AttributedStmt * Create(const ASTContext &C, SourceLocation Loc, ArrayRef< const Attr * > Attrs, Stmt *SubStmt)
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condition evaluates to false; ...
OpaqueValueExpr * getOpaqueValue() const
getOpaqueValue - Return the opaque value placeholder.
A builtin binary operation expression such as "x + y" or "x <= y".
SourceLocation getExprLoc() const
BreakStmt - This represents a break.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
void setOrigin(const CXXRecordDecl *Rec)
bool isAmbiguous(CanQualType BaseType)
Determine whether the path from the most-derived type to the given base type is ambiguous (i....
QualType getType() const
Retrieves the type of the base class.
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
Represents binding an expression to a temporary.
CXXCatchStmt - This represents a C++ catch block.
SourceLocation getBeginLoc() const LLVM_READONLY
VarDecl * getExceptionDecl() const
QualType getCaughtType() const
Represents a call to a C++ constructor.
Represents a C++ conversion function within a class.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
DeclStmt * getBeginStmt()
DeclStmt * getRangeStmt()
Represents an explicit C++ type conversion that uses "functional" notation (C++ [expr....
Represents a call to a member function that may be written either with member call syntax (e....
A call to an overloaded operator written using operator syntax.
Represents a C++ struct/union/class.
static CXXRecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl=nullptr)
An expression "T()" which creates an rvalue of a non-class type T.
Represents a C++ nested-name-specifier or a global scope specifier.
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context.
static CXXTryStmt * Create(const ASTContext &C, SourceLocation tryLoc, CompoundStmt *tryBlock, ArrayRef< Stmt * > handlers)
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
static CanQual< Type > CreateUnsafe(QualType Other)
Represents the body of a CapturedStmt, and serves as its DeclContext.
static DeclContext * castToDeclContext(const CapturedDecl *D)
void setContextParam(unsigned i, ImplicitParamDecl *P)
void setParam(unsigned i, ImplicitParamDecl *P)
static CapturedDecl * Create(ASTContext &C, DeclContext *DC, unsigned NumParams)
Describes the capture of either a variable, or 'this', or variable-length array type.
This captures a statement into a function.
Stmt * getCapturedStmt()
Retrieve the statement being captured.
static CapturedStmt * Create(const ASTContext &Context, Stmt *S, CapturedRegionKind Kind, ArrayRef< Capture > Captures, ArrayRef< Expr * > CaptureInits, CapturedDecl *CD, RecordDecl *RD)
CaseStmt - Represent a case statement.
static CaseStmt * Create(const ASTContext &Ctx, Expr *lhs, Expr *rhs, SourceLocation caseLoc, SourceLocation ellipsisLoc, SourceLocation colonLoc)
Build a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
Represents the canonical version of C arrays with a specified constant size.
ContinueStmt - This represents a continue.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isFileContext() const
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
void addDecl(Decl *D)
Add the declaration D into this context.
bool isStdNamespace() const
bool isFunctionOrMethod() const
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
bool isSingleDecl() const
A reference to a declared variable, function, enum, etc.
SourceLocation getLocation() const
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
const Decl * getSingleDecl() const
SourceLocation getBeginLoc() const LLVM_READONLY
Decl - This represents one declaration (or definition), e.g.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
static Decl * castFromDeclContext(const DeclContext *)
bool isInvalidDecl() const
SourceLocation getLocation() const
void setImplicit(bool I=true)
void setLocation(SourceLocation L)
DeclContext * getDeclContext()
SourceLocation getTypeSpecEndLoc() const
SourceLocation getTypeSpecStartLoc() const
SourceLocation getBeginLoc() const LLVM_READONLY
TypeSourceInfo * getTypeSourceInfo() const
SourceLocation getDefaultLoc() const
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
DoStmt - This represents a 'do/while' stmt.
bool isClosed() const
Returns true if this enum is either annotated with enum_extensibility(closed) or isn't annotated with...
EvaluatedExprVisitor - This class visits 'Expr *'s.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isUnusedResultAWarning(const Expr *&WarnExpr, SourceLocation &Loc, SourceRange &R1, SourceRange &R2, ASTContext &Ctx) const
isUnusedResultAWarning - Return true if this immediate expression should be warned about if the resul...
bool isValueDependent() const
Determines whether the value of this expression depends on.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, 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.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
Decl * getReferencedDeclOfCallee()
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isKnownToHaveBooleanValue(bool Semantic=true) const
isKnownToHaveBooleanValue - Return true if this is an integer expression that is known to return 0 or...
Represents difference between two FPOptions values.
FPOptionsOverride getChangesFrom(const FPOptions &Base) const
Return difference with the given option set.
Represents a member of a struct/union/class.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
SourceLocation getRParenLoc() const
SourceLocation getBeginLoc() const
FullExpr - Represents a "full-expression" node.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
void setUsesSEHTry(bool UST)
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
QualType getReturnType() const
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isMain() const
Determines whether this function is "main", which is the entry point into an executable program.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isOverloadedOperator() const
Whether this function declaration represents an C++ overloaded operator, e.g., "operator+".
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
Represents a prototype with parameter type info, e.g.
Declaration of a template function.
FunctionType - C99 6.7.5.3 - Function Declarators.
static StringRef getNameForCallConv(CallingConv CC)
bool getNoReturnAttr() const
Determine whether this function type includes the GNU noreturn attribute.
QualType getReturnType() const
GotoStmt - This represents a direct goto.
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static IfStmt * Create(const ASTContext &Ctx, SourceLocation IL, IfStatementKind Kind, Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LPL, SourceLocation RPL, Stmt *Then, SourceLocation EL=SourceLocation(), Stmt *Else=nullptr)
Create an IfStmt.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
IndirectGotoStmt - This represents an indirect goto.
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
Describes an entity that is being initialized.
static InitializedEntity InitializeResult(SourceLocation ReturnLoc, QualType Type)
Create the initialization entity for the result of a function.
static InitializedEntity InitializeRelatedResult(ObjCMethodDecl *MD, QualType Type)
Create the initialization entity for a related result.
unsigned allocateManglingNumber() const
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Represents the declaration of a label.
void setLocStart(SourceLocation L)
LabelStmt * getStmt() const
void setStmt(LabelStmt *T)
bool isMSAsmLabel() const
LabelStmt - Represents a label, which has a substatement.
Represents the results of name lookup.
bool empty() const
Return true if no decls were found.
SourceLocation getKwLoc() const
Representation of a Microsoft __if_exists or __if_not_exists statement with a dependent name.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const
Determine if the declaration obeys the reserved identifier rules of the given language.
A C++ nested-name-specifier augmented with source location information.
NullStmt - This is the null statement ";": C99 6.8.3p3.
An expression that sends a message to the given Objective-C object or class.
ObjCMethodDecl - Represents an instance or class method declaration.
Represents a pointer to an Objective C object.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
OverloadCandidateSet - A set of overload candidates, used in C++ overload resolution (C++ 13....
@ CSK_Normal
Normal lookup.
void NoteCandidates(PartialDiagnosticAt PA, Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef< Expr * > Args, StringRef Opc="", SourceLocation Loc=SourceLocation(), llvm::function_ref< bool(OverloadCandidate &)> Filter=[](OverloadCandidate &) { return true;})
When overload resolution fails, prints diagnostic messages containing the candidates in the candidate...
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
const Expr * getSubExpr() const
Represents a parameter to a function.
ParsedAttributes - A collection of parsed attributes.
Wrapper for source info for pointers.
SourceLocation getStarLoc() const
IdentifierTable & getIdentifierTable()
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType withConst() const
bool isTriviallyCopyConstructibleType(const ASTContext &Context) const
Return true if this is a trivially copyable type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool isConstQualified() const
Determine whether this type is const-qualified.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Represents a struct/union/class.
static RecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl *PrevDecl=nullptr)
virtual void completeDefinition()
Note that the definition of this type is now complete.
void setCapturedRecord()
Mark the record as a record for captured variables in CapturedStmt construct.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
void setRetValue(Expr *E)
static ReturnStmt * Create(const ASTContext &Ctx, SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
Create a return statement.
static SEHExceptStmt * Create(const ASTContext &C, SourceLocation ExceptLoc, Expr *FilterExpr, Stmt *Block)
static SEHFinallyStmt * Create(const ASTContext &C, SourceLocation FinallyLoc, Stmt *Block)
Represents a __leave statement.
static SEHTryStmt * Create(const ASTContext &C, bool isCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)
Scope - A scope is a transient data structure that is used while parsing the program.
unsigned getDepth() const
Returns the depth of this scope. The translation-unit has scope depth 0.
bool Contains(const Scope &rhs) const
Returns if rhs has a higher scope depth than this.
LabelDecl * getPrecedingLabel() const
Get the label that precedes this scope.
unsigned getFlags() const
getFlags - Return the flags for this scope.
Scope * getContinueParent()
getContinueParent - Return the closest scope that a continue statement would be affected by.
bool isLoopScope() const
Return true if this scope is a loop.
bool isSEHTryScope() const
Determine whether this scope is a SEH '__try' block.
Scope * getBreakParent()
getBreakParent - Return the closest scope that a break statement would be affected by.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
bool isBreakOrContinueScope() const
Determine whether this is a scope which can have 'break' or 'continue' statements embedded into it.
bool isConditionVarScope() const
bool isFunctionScope() const
isFunctionScope() - Return true if this scope is a function scope.
bool isOpenACCComputeConstructScope() const
Determine whether this scope is the statement associated with an OpenACC Compute construct directive.
bool isOpenMPLoopScope() const
Determine whether this scope is a loop having OpenMP loop directive attached.
@ SwitchScope
This is a scope that corresponds to a switch statement.
A generic diagnostic builder for errors which may or may not be deferred.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
CUDAFunctionTarget CurrentTarget()
Gets the CUDA target for the current context.
SemaDiagnosticBuilder DiagIfDeviceCode(SourceLocation Loc, unsigned DiagID)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as device c...
StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, Stmt *First, Expr *collection, SourceLocation RParenLoc)
StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body)
FinishObjCForCollectionStmt - Attach the body to a objective-C foreach statement.
bool inferObjCARCLifetime(ValueDecl *decl)
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable,...
void setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, unsigned Level)
Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) for FD based on DSA for the...
std::pair< VarDecl *, Expr * > get() const
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
Sema - This implements semantic analysis and AST building for C.
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)
Package the given type and TSI into a ParsedType.
SmallVector< Scope *, 2 > CurrentSEHFinally
Stack of active SEH __finally scopes. Can be empty.
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
Scope * getCurScope() const
Retrieve the parser's current scope.
StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope, LabelDecl *Label, SourceLocation LabelLoc)
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 ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope, LabelDecl *Label, SourceLocation LabelLoc)
StmtResult ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, LabelDecl *TheDecl)
StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, Scope *CurScope)
void setFunctionHasBranchIntoScope()
ExprResult ActOnCaseExpr(SourceLocation CaseLoc, ExprResult Val)
StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue=true)
FieldDecl * BuildCaptureField(RecordDecl *RD, const sema::Capture &Capture)
Build a FieldDecl suitable to hold the given capture.
AssignConvertType CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, bool Diagnose=true, bool DiagnoseCFAudited=false, bool ConvertRHS=true)
Check assignment constraints for an assignment of RHS to LHSType.
StmtResult BuildIfStmt(SourceLocation IfLoc, IfStatementKind StatementKind, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc, Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal)
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
ExprResult UsualUnaryConversions(Expr *E)
UsualUnaryConversions - Performs various conversions that are common to most operators (C99 6....
void DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc)
Look for instances where it is likely the comma operator is confused with another operator.
void DiagnoseExceptionUse(SourceLocation Loc, bool IsTry)
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
std::unique_ptr< sema::FunctionScopeInfo, PoppedFunctionScopeDeleter > PoppedFunctionScopePtr
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
void PopExpressionEvaluationContext()
StmtResult ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)
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...
void DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID)
DiagnoseUnusedExprResult - If the statement passed in is an expression whose result is unused,...
FPOptions & getCurFPFeatures()
Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, TranslationUnitKind TUKind=TU_Complete, CodeCompleteConsumer *CompletionConsumer=nullptr)
@ UPPC_Expression
An arbitrary expression.
const LangOptions & getLangOpts() const
StmtResult ActOnWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, ConditionResult Cond, SourceLocation RParenLoc, Stmt *Body)
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...
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.
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 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)
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, AllowFoldKind CanFold=AllowFoldKind::No)
VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...
StmtResult ActOnMSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, CXXScopeSpec &SS, UnqualifiedId &Name, Stmt *Nested)
@ 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
void ActOnStartSEHFinallyBlock()
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void ActOnAbortSEHFinallyBlock()
friend class InitializationSequence
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...
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
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 ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
bool isMacroBodyExpansion(SourceLocation Loc) const
Tests whether the given source location represents the expansion of a macro body.
bool isInSystemMacro(SourceLocation loc) const
Returns whether Loc is expanded from a macro in a system header.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
static std::tuple< bool, const Attr *, const Attr * > determineLikelihoodConflict(const Stmt *Then, const Stmt *Else)
static const Attr * getLikelihoodAttr(const Stmt *S)
SourceLocation getBeginLoc() const LLVM_READONLY
SwitchStmt - This represents a 'switch' stmt.
static SwitchStmt * Create(const ASTContext &Ctx, Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LParenLoc, SourceLocation RParenLoc)
Create a switch statement.
SwitchCase * getSwitchCaseList()
DeclStmt * getConditionVariableDeclStmt()
If this SwitchStmt has a condition variable, return the faux DeclStmt associated with the creation of...
void setAllEnumCasesCovered()
Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a switch over an enum value then ...
Represents the declaration of a struct/union/class/enum.
void startDefinition()
Starts the definition of this tag declaration.
TemplateSpecCandidateSet - A set of generalized overload candidates, used in template specializations...
void NoteCandidates(Sema &S, SourceLocation Loc)
NoteCandidates - When no template specialization match is found, prints diagnostic messages containin...
Base wrapper for a particular "section" of type source info.
QualType getType() const
Get the type for which this source info wrapper provides information.
T castAs() const
Convert to the specified TypeLoc type, asserting that this TypeLoc is of the desired type.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isRValueReferenceType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool containsErrors() const
Whether this type is an error type.
EnumDecl * castAsEnumDecl() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isObjectType() const
Determine whether this type is an object type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
TypeClass getTypeClass() const
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
Represents a C++ unqualified-id that has been parsed.
void setType(QualType newType)
Represents a variable declaration or definition.
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool isExceptionVariable() const
Determine whether this variable is the exception variable in a C++ catch statememt or an Objective-C ...
const Expr * getInit() const
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
bool hasDependentAlignment() const
Determines if this variable's alignment is dependent.
Represents a C array with a specified size that is not an integer-constant-expression.
static WhileStmt * Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, Stmt *Body, SourceLocation WL, SourceLocation LParenLoc, SourceLocation RParenLoc)
Create a while statement.
ValueDecl * getVariable() const
bool isVariableCapture() const
SourceLocation getLocation() const
Retrieve the location at which this variable was captured.
bool isVLATypeCapture() const
bool isThisCapture() const
bool isReferenceCapture() const
Retains information about a captured region.
unsigned short OpenMPLevel
unsigned short CapRegionKind
The kind of captured region.
RecordDecl * TheRecordDecl
The captured record type.
CapturedDecl * TheCapturedDecl
The CapturedDecl for this statement.
QualType ReturnType
ReturnType - The target type of return statements in this context, or null if unknown.
SmallVector< Capture, 4 > Captures
Captures - The captures.
bool HasImplicitReturnType
Contains information about the compound statement currently being parsed.
FPOptions InitialFPFeatures
FP options at the beginning of the compound statement, prior to any pragma.
void setHasEmptyLoopBodies()
Retains information about a function, method, or block that is currently being parsed.
llvm::PointerIntPair< SwitchStmt *, 1, bool > SwitchInfo
A SwitchStmt, along with a flag indicating if its list of case statements is incomplete (because we d...
SourceLocation FirstCXXOrObjCTryLoc
First C++ 'try' or ObjC @try statement in the current function.
SourceLocation FirstCoroutineStmtLoc
First coroutine statement in the current function.
enum clang::sema::FunctionScopeInfo::@340304006310276167163023075110222134352007243353 FirstTryType
StringRef getFirstCoroutineStmtKeyword() const
SourceLocation FirstReturnLoc
First 'return' statement in the current function.
SourceLocation FirstSEHTryLoc
First SEH '__try' statement in the current function.
void setHasCXXTry(SourceLocation TryLoc)
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound statement scopes in the function.
void setHasSEHTry(SourceLocation TryLoc)
SmallVector< SwitchInfo, 8 > SwitchStack
SwitchStack - This is the current set of active switch statements in the block.
CXXMethodDecl * CallOperator
The lambda's compiler-generated operator().
Provides information about an attempted template argument deduction, whose success or failure was des...
TemplateArgument SecondArg
The second template argument to which the template argument deduction failure refers.
TemplateArgument FirstArg
The first template argument to which the template argument deduction failure refers.
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
bool This(InterpState &S, CodePtr OpPC)
bool Cast(InterpState &S, CodePtr OpPC)
void checkExprLifetimeMustTailArg(Sema &SemaRef, const InitializedEntity &Entity, Expr *Init)
Check that the lifetime of the given expr (and its subobjects) is sufficient, assuming that it is pas...
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ OR_Deleted
Succeeded, but refers to a deleted function.
@ OR_Success
Overload resolution succeeded.
bool isReservedInAllContexts(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved in all contexts.
IfStatementKind
In an if statement, this denotes whether the statement is a constexpr or consteval if statement.
Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)
Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...
@ RQ_None
No ref-qualifier was provided.
@ OCD_AllCandidates
Requests that all candidates be shown.
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
SmallVector< Attr *, 4 > AttrVec
AttrVec - A vector of Attr, which is how they are stored on the AST.
nullptr
This class represents a compute construct, representing a 'Kind' of βparallelβ, 'serial',...
CapturedRegionKind
The different kinds of captured statement.
@ Result
The result type of a method or function.
const FunctionProtoType * T
AssignConvertType
AssignConvertType - All of the 'assignment' semantic checks return this enum to indicate whether the ...
bool hasArmZT0State(const FunctionDecl *FD)
Returns whether the given FunctionDecl has Arm ZT0 state.
@ Struct
The "struct" keyword.
@ Type
The name was classified as a type.
bool isLambdaConversionOperator(CXXConversionDecl *C)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ VK_XValue
An x-value expression is a reference to an object with independent storage but which can be "moved",...
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Expr * IgnoreParensSingleStep(Expr *E)
Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)
DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor
TemplateDeductionResult
Describes the result of template argument deduction.
@ Success
Template argument deduction was successful.
@ Inconsistent
Template argument deduction produced inconsistent deduced values for the given template parameter.
@ AlreadyDiagnosed
Some error which was already diagnosed.
U cast(CodeGen::Address addr)
@ CaseValue
Expression in a case label.
bool IsArmStreamingFunction(const FunctionDecl *FD, bool IncludeLocallyStreaming)
Returns whether the given FunctionDecl has an __arm[_locally]_streaming attribute.
ActionResult< Expr * > ExprResult
@ CapturedContext
Parameter for captured context.
ActionResult< Stmt * > StmtResult
bool hasArmZAState(const FunctionDecl *FD)
Returns whether the given FunctionDecl has Arm ZA state.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
EvalResult is a struct with detailed info about an evaluated expression.
@ MoveEligibleAndCopyElidable
bool isMoveEligible() const
bool isCopyElidable() const
const VarDecl * Candidate
static CatchHandlerType getEmptyKey()
static CatchHandlerType getTombstoneKey()
static unsigned getHashValue(const CatchHandlerType &Base)
static bool isEqual(const CatchHandlerType &LHS, const CatchHandlerType &RHS)