39#include "llvm/ADT/ArrayRef.h"
40#include "llvm/ADT/DenseMap.h"
41#include "llvm/ADT/STLExtras.h"
42#include "llvm/ADT/STLForwardCompat.h"
43#include "llvm/ADT/SmallVector.h"
44#include "llvm/ADT/StringExtras.h"
72 bool HasLeadingEmptyMacro) {
101 Diag(
decl->getLocation(), diag::err_non_variable_decl_in_for);
102 decl->setInvalidDecl();
108 var->setInit(
nullptr);
121 var->setType(
type.withConst());
122 var->setARCPseudoStrong(
true);
135 enum { Equality, Inequality, Relational, ThreeWay } Kind;
138 if (!Op->isComparisonOp())
141 if (Op->getOpcode() == BO_EQ)
143 else if (Op->getOpcode() == BO_NE)
145 else if (Op->getOpcode() == BO_Cmp)
148 assert(Op->isRelationalOp());
151 Loc = Op->getOperatorLoc();
152 CanAssign = Op->getLHS()->IgnoreParenImpCasts()->isLValue();
154 switch (Op->getOperator()) {
158 case OO_ExclaimEqual:
163 case OO_GreaterEqual:
174 Loc = Op->getOperatorLoc();
175 CanAssign = Op->getArg(0)->IgnoreParenImpCasts()->isLValue();
186 S.
Diag(
Loc, diag::warn_unused_comparison)
192 if (Kind == Inequality)
193 S.
Diag(
Loc, diag::note_inequality_comparison_to_or_assign)
195 else if (Kind == Equality)
196 S.
Diag(
Loc, diag::note_equality_comparison_to_assign)
208 StringRef Msg = A->getMessage();
212 return S.
Diag(
Loc, diag::warn_unused_return_type)
213 << IsCtor << A << OffendingDecl <<
false << R1 << R2;
215 return S.
Diag(
Loc, diag::warn_unused_constructor)
216 << A <<
false << R1 << R2;
217 return S.
Diag(
Loc, diag::warn_unused_result) << A <<
false << R1 << R2;
221 return S.
Diag(
Loc, diag::warn_unused_return_type)
222 << IsCtor << A << OffendingDecl <<
true << Msg << R1 << R2;
224 return S.
Diag(
Loc, diag::warn_unused_constructor)
225 << A <<
true << Msg << R1 << R2;
226 return S.
Diag(
Loc, diag::warn_unused_result) << A <<
true << Msg << R1 << R2;
235void DiagnoseUnused(
Sema &S,
const Expr *
E, std::optional<unsigned> DiagID) {
236 bool NoDiscardOnly = !DiagID.has_value();
252 const Expr *WarnExpr;
258 if (!NoDiscardOnly) {
279 if (
const FullExpr *Temps = dyn_cast<FullExpr>(
E))
280 E = Temps->getSubExpr();
282 E = TempExpr->getSubExpr();
288 if (
const auto *Cast = dyn_cast<CastExpr>(
E))
289 if (
Cast->getCastKind() == CK_NoOp ||
290 Cast->getCastKind() == CK_ConstructorConversion ||
291 Cast->getCastKind() == CK_IntegralCast)
292 E =
Cast->getSubExpr()->IgnoreImpCasts();
294 if (
const CallExpr *CE = dyn_cast<CallExpr>(
E)) {
298 auto [OffendingDecl, A] = CE->getUnusedResultAttr(S.
Context);
300 cast_or_null<WarnUnusedResultAttr>(A),
Loc, R1, R2,
308 if (
const Decl *FD = CE->getCalleeDecl()) {
311 if (FD->hasAttr<PureAttr>()) {
312 S.
Diag(
Loc, diag::warn_unused_call) << R1 << R2 <<
"pure";
315 if (FD->hasAttr<ConstAttr>()) {
316 S.
Diag(
Loc, diag::warn_unused_call) << R1 << R2 <<
"const";
320 }
else if (
const auto *CE = dyn_cast<CXXConstructExpr>(
E)) {
322 const NamedDecl *OffendingDecl =
nullptr;
323 const auto *A = Ctor->
getAttr<WarnUnusedResultAttr>();
325 OffendingDecl = Ctor->getParent();
326 A = OffendingDecl->
getAttr<WarnUnusedResultAttr>();
332 }
else if (
const auto *ILE = dyn_cast<InitListExpr>(
E)) {
333 if (
const TagDecl *TD = ILE->getType()->getAsTagDecl()) {
339 }
else if (ShouldSuppress)
344 if (S.
getLangOpts().ObjCAutoRefCount && ME->isDelegateInitCall()) {
345 S.
Diag(
Loc, diag::err_arc_unused_init_message) << R1;
356 const Expr *Source = POE->getSyntacticForm();
358 if (S.
LangOpts.OpenMP && isa<CallExpr>(Source) &&
359 POE->getNumSemanticExprs() == 1 &&
360 isa<CallExpr>(POE->getSemanticExpr(0)))
361 return DiagnoseUnused(S, POE->getSemanticExpr(0), DiagID);
362 if (isa<ObjCSubscriptRefExpr>(Source))
363 DiagID = diag::warn_unused_container_subscript_expr;
364 else if (isa<ObjCPropertyRefExpr>(Source))
365 DiagID = diag::warn_unused_property_expr;
367 = dyn_cast<CXXFunctionalCastExpr>(
E)) {
368 const Expr *
E = FC->getSubExpr();
370 E = TE->getSubExpr();
371 if (isa<CXXTemporaryObjectExpr>(
E))
374 if (
const CXXRecordDecl *RD = CE->getType()->getAsCXXRecordDecl())
375 if (!RD->getAttr<WarnUnusedAttr>())
391 S.
Diag(
Loc, diag::warn_unused_voidptr)
401 S.
Diag(
Loc, diag::warn_unused_volatile) << R1 << R2;
408 if (DiagID == diag::warn_unused_comma_left_operand && S.
isSFINAEContext())
412 S.
PDiag(*DiagID) << R1 << R2);
417 DiagnoseUnused(*
this,
E, std::nullopt);
422 S =
Label->getSubStmt();
424 const Expr *
E = dyn_cast_if_present<Expr>(S);
428 DiagnoseUnused(*
this,
E, DiagID);
453 const unsigned NumElts = Elts.size();
458 const unsigned MixedDeclsCodeID =
getLangOpts().C99
459 ? diag::warn_mixed_decls_code
460 : diag::ext_mixed_decls_code;
465 for (; i != NumElts && isa<DeclStmt>(Elts[i]); ++i)
469 for (; i != NumElts && !isa<DeclStmt>(Elts[i]); ++i)
473 Decl *
D = *cast<DeclStmt>(Elts[i])->decl_begin();
483 for (
unsigned i = 0; i != NumElts - 1; ++i)
519 auto CheckAndFinish = [&](
Expr *
E) {
526 llvm::APSInt TempVal;
546 if (Converted.
get() == Val.
get())
547 Converted = CheckAndFinish(Val.
get());
555 assert((LHSVal.
isInvalid() || LHSVal.
get()) &&
"missing LHS value");
558 "missing RHS value");
561 Diag(CaseLoc, diag::err_case_not_in_switch);
572 Diag(CaseLoc, diag::err_acc_branch_in_out_compute_construct)
578 CaseLoc, DotDotDotLoc, ColonLoc);
584 cast<CaseStmt>(S)->setSubStmt(SubStmt);
591 Diag(DefaultLoc, diag::err_default_not_in_switch);
597 Diag(DefaultLoc, diag::err_acc_branch_in_out_compute_construct)
612 Diag(IdentLoc, diag::err_redefinition_of_label) << TheDecl->
getDeclName();
620 Diag(IdentLoc, diag::warn_reserved_extern_symbol)
621 << TheDecl << static_cast<int>(Status);
625 if (
getCurScope()->isInOpenACCComputeConstructScope())
647 for (
const auto *A : Attrs) {
648 if (A->getKind() == attr::MustTail) {
663 if (!SemanticAttrs.empty())
679 if (!checkMustTailAttr(St, MTA))
685 auto IgnoreImplicitAsWritten = [](
Expr *
E) ->
Expr * {
696bool Sema::checkMustTailAttr(
const Stmt *St,
const Attr &MTA) {
698 "musttail cannot be checked from a dependent context");
701 auto IgnoreParenImplicitAsWritten = [](
const Expr *
E) ->
const Expr * {
707 const Expr *
E = cast<ReturnStmt>(St)->getRetValue();
708 const auto *CE = dyn_cast_or_null<CallExpr>(IgnoreParenImplicitAsWritten(
E));
715 if (
const auto *EWC = dyn_cast<ExprWithCleanups>(
E)) {
716 if (EWC->cleanupsHaveSideEffects()) {
717 Diag(St->
getBeginLoc(), diag::err_musttail_needs_trivial_args) << &MTA;
728 ft_non_static_member,
729 ft_pointer_to_member,
730 } MemberType = ft_non_member;
735 } CallerType, CalleeType;
738 bool IsCallee) ->
bool {
739 if (isa<CXXConstructorDecl, CXXDestructorDecl>(CMD)) {
741 << IsCallee << isa<CXXDestructorDecl>(CMD);
743 Diag(CMD->getBeginLoc(), diag::note_musttail_structors_forbidden)
744 << isa<CXXDestructorDecl>(CMD);
749 Type.MemberType = FuncType::ft_static_member;
751 Type.This = CMD->getFunctionObjectParameterType();
752 Type.MemberType = FuncType::ft_non_static_member;
758 const auto *CallerDecl = dyn_cast<FunctionDecl>(
CurContext);
769 Diag(St->
getBeginLoc(), diag::err_musttail_forbidden_from_this_context)
772 }
else if (
const auto *CMD = dyn_cast<CXXMethodDecl>(
CurContext)) {
774 if (!GetMethodType(CMD, CallerType,
false))
782 const auto *CalleeBinOp = dyn_cast<BinaryOperator>(CalleeExpr);
784 ? CE->getCalleeDecl()->getBeginLoc()
789 dyn_cast_or_null<CXXMethodDecl>(CE->getCalleeDecl())) {
791 if (!GetMethodType(CMD, CalleeType,
true))
793 }
else if (CalleeBinOp && CalleeBinOp->isPtrMemOp()) {
797 CalleeType.This =
QualType(MPT->getClass(), 0);
799 CalleeType.MemberType = FuncType::ft_pointer_to_member;
800 }
else if (isa<CXXPseudoDestructorExpr>(CalleeExpr)) {
812 if (!CalleeType.Func || !CallerType.Func) {
814 if (!CalleeType.Func && CE->getDirectCallee()) {
815 Diag(CE->getDirectCallee()->getBeginLoc(),
816 diag::note_musttail_fix_non_prototype);
818 if (!CallerType.Func)
819 Diag(CallerDecl->getBeginLoc(), diag::note_musttail_fix_non_prototype);
830 if (CallerType.Func->getCallConv() != CalleeType.Func->getCallConv()) {
831 if (
const auto *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl()))
833 <<
true << ND->getDeclName();
835 Diag(St->
getBeginLoc(), diag::err_musttail_callconv_mismatch) <<
false;
836 Diag(CalleeLoc, diag::note_musttail_callconv_mismatch)
843 if (CalleeType.Func->isVariadic() || CallerType.Func->isVariadic()) {
848 const auto *CalleeDecl = CE->getCalleeDecl();
849 if (CalleeDecl && CalleeDecl->hasAttr<CXX11NoReturnAttr>()) {
855 if (CallerType.This.isNull() != CalleeType.This.isNull()) {
856 if (
const auto *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl())) {
858 << CallerType.MemberType << CalleeType.MemberType <<
true
859 << ND->getDeclName();
860 Diag(CalleeLoc, diag::note_musttail_callee_defined_here)
861 << ND->getDeclName();
864 << CallerType.MemberType << CalleeType.MemberType <<
false;
869 auto CheckTypesMatch = [
this](FuncType CallerType, FuncType CalleeType,
879 unsigned Select) ->
bool {
887 if (!CallerType.This.isNull() &&
891 if (!DoTypesMatch(CallerType.Func->getReturnType(),
895 if (CallerType.Func->getNumParams() != CalleeType.Func->getNumParams()) {
897 << CalleeType.Func->getNumParams();
903 size_t N = CallerType.Func->getNumParams();
904 for (
size_t I = 0; I < N; I++) {
905 if (!DoTypesMatch(CalleeParams[I], CallerParams[I],
907 PD << static_cast<int>(I) + 1;
916 if (!CheckTypesMatch(CallerType, CalleeType, PD)) {
917 if (
const auto *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl()))
919 <<
true << ND->getDeclName();
930 for (
auto ArgExpr : CE->arguments()) {
932 Context, ArgExpr->getType(),
false);
944 CommaVisitor(
Sema &SemaRef) : Inherited(SemaRef.Context), SemaRef(SemaRef) {}
946 if (
E->getOpcode() == BO_Comma)
962 bool ConstevalOrNegatedConsteval =
966 Expr *CondExpr = Cond.
get().second;
967 assert((CondExpr || ConstevalOrNegatedConsteval) &&
968 "If statement: missing condition");
972 CommaVisitor(*this).Visit(CondExpr);
974 if (!ConstevalOrNegatedConsteval && !elseStmt)
977 if (ConstevalOrNegatedConsteval ||
979 auto DiagnoseLikelihood = [&](
const Stmt *S) {
982 diag::warn_attribute_has_no_effect_on_compile_time_if)
983 << A << ConstevalOrNegatedConsteval << A->getRange();
985 diag::note_attribute_has_no_effect_on_compile_time_if_here)
986 << ConstevalOrNegatedConsteval
993 DiagnoseLikelihood(thenStmt);
994 DiagnoseLikelihood(elseStmt);
996 std::tuple<bool, const Attr *, const Attr *> LHC =
998 if (std::get<0>(LHC)) {
999 const Attr *ThenAttr = std::get<1>(LHC);
1000 const Attr *ElseAttr = std::get<2>(LHC);
1002 diag::warn_attributes_likelihood_ifstmt_conflict)
1003 << ThenAttr << ThenAttr->
getRange();
1005 << ElseAttr << ElseAttr->
getRange();
1009 if (ConstevalOrNegatedConsteval) {
1015 if (FD && FD->isImmediateFunction())
1019 Diags.
Report(IfLoc, diag::warn_consteval_if_always_true) << Immediate;
1022 return BuildIfStmt(IfLoc, StatementKind, LParenLoc, InitStmt, Cond, RParenLoc,
1023 thenStmt, ElseLoc, elseStmt);
1036 isa<ObjCAvailabilityCheckExpr>(Cond.
get().second))
1040 Cond.
get().first, Cond.
get().second, LParenLoc,
1041 RParenLoc, thenStmt, ElseLoc, elseStmt);
1045 struct CaseCompareFunctor {
1046 bool operator()(
const std::pair<llvm::APSInt, CaseStmt*> &LHS,
1047 const llvm::APSInt &RHS) {
1048 return LHS.first < RHS;
1050 bool operator()(
const std::pair<llvm::APSInt, CaseStmt*> &LHS,
1051 const std::pair<llvm::APSInt, CaseStmt*> &RHS) {
1052 return LHS.first < RHS.first;
1054 bool operator()(
const llvm::APSInt &LHS,
1055 const std::pair<llvm::APSInt, CaseStmt*> &RHS) {
1056 return LHS < RHS.first;
1064 const std::pair<llvm::APSInt, CaseStmt*>& rhs) {
1065 if (lhs.first < rhs.first)
1068 if (lhs.first == rhs.first &&
1069 lhs.second->getCaseLoc() < rhs.second->getCaseLoc())
1076static bool CmpEnumVals(
const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,
1077 const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)
1079 return lhs.first < rhs.first;
1084static bool EqEnumVals(
const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,
1085 const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)
1087 return lhs.first == rhs.first;
1093 if (
const auto *FE = dyn_cast<FullExpr>(
E))
1094 E = FE->getSubExpr();
1095 while (
const auto *ImpCast = dyn_cast<ImplicitCastExpr>(
E)) {
1096 if (ImpCast->getCastKind() != CK_IntegralCast)
break;
1097 E = ImpCast->getSubExpr();
1107 SwitchConvertDiagnoser(
Expr *Cond)
1113 return S.
Diag(
Loc, diag::err_typecheck_statement_requires_integer) <<
T;
1118 return S.
Diag(
Loc, diag::err_switch_incomplete_class_type)
1124 return S.
Diag(
Loc, diag::err_switch_explicit_conversion) <<
T << ConvTy;
1135 return S.
Diag(
Loc, diag::err_switch_multiple_conversions) <<
T;
1146 llvm_unreachable(
"conversion functions are permitted");
1148 } SwitchDiagnoser(Cond);
1157 Cond = CondResult.
get();
1170 Expr *CondExpr = Cond.
get().second;
1171 assert((Cond.
isInvalid() || CondExpr) &&
"switch with no condition");
1184 Diag(SwitchLoc, diag::warn_bool_switch_condition)
1192 LParenLoc, RParenLoc);
1198static void AdjustAPSInt(llvm::APSInt &Val,
unsigned BitWidth,
bool IsSigned) {
1199 Val = Val.extOrTrunc(BitWidth);
1200 Val.setIsSigned(IsSigned);
1206 unsigned UnpromotedWidth,
bool UnpromotedSign) {
1214 if (UnpromotedWidth < Val.getBitWidth()) {
1215 llvm::APSInt ConvVal(Val);
1216 AdjustAPSInt(ConvVal, UnpromotedWidth, UnpromotedSign);
1217 AdjustAPSInt(ConvVal, Val.getBitWidth(), Val.isSigned());
1233 const Expr *CaseExpr,
1234 EnumValsTy::iterator &EI,
1235 EnumValsTy::iterator &EIEnd,
1236 const llvm::APSInt &Val) {
1242 if (
const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
1251 if (ED->
hasAttr<FlagEnumAttr>())
1254 while (EI != EIEnd && EI->first < Val)
1257 if (EI != EIEnd && EI->first == Val)
1270 if (!CondEnumType || !CaseEnumType)
1277 if (!CaseEnumType->getDecl()->getIdentifier() &&
1278 !CaseEnumType->getDecl()->getTypedefNameForAnonDecl())
1284 S.
Diag(Case->
getExprLoc(), diag::warn_comparison_of_mixed_enum_types_switch)
1294 assert(SS ==
getCurFunction()->SwitchStack.back().getPointer() &&
1295 "switch stack missing push/pop!");
1300 SS->
setBody(BodyStmt, SwitchLoc);
1314 const Expr *CondExprBeforePromotion = CondExpr;
1320 bool HasDependentValue
1329 unsigned CondWidthBeforePromotion
1331 bool CondIsSignedBeforePromotion
1338 CaseValsTy CaseVals;
1341 typedef std::vector<std::pair<llvm::APSInt, CaseStmt*> > CaseRangesTy;
1342 CaseRangesTy CaseRanges;
1346 bool CaseListIsErroneous =
false;
1354 if (
DefaultStmt *DS = dyn_cast<DefaultStmt>(SC)) {
1355 if (TheDefaultStmt) {
1356 Diag(DS->getDefaultLoc(), diag::err_multiple_default_labels_defined);
1363 CaseListIsErroneous =
true;
1365 TheDefaultStmt = DS;
1373 HasDependentValue =
true;
1379 const Expr *LoBeforePromotion = Lo;
1386 CondIsSignedBeforePromotion);
1398 HasDependentValue =
true;
1401 CaseRanges.push_back(std::make_pair(LoVal, CS));
1403 CaseVals.push_back(std::make_pair(LoVal, CS));
1407 if (!HasDependentValue) {
1410 llvm::APSInt ConstantCondValue;
1411 bool HasConstantCond =
false;
1412 if (!TheDefaultStmt) {
1417 ConstantCondValue =
Result.Val.getInt();
1418 assert(!HasConstantCond ||
1419 (ConstantCondValue.getBitWidth() == CondWidth &&
1420 ConstantCondValue.isSigned() == CondIsSigned));
1421 Diag(SwitchLoc, diag::warn_switch_default);
1423 bool ShouldCheckConstantCond = HasConstantCond;
1428 if (!CaseVals.empty()) {
1429 for (
unsigned i = 0, e = CaseVals.size(); i != e; ++i) {
1430 if (ShouldCheckConstantCond &&
1431 CaseVals[i].first == ConstantCondValue)
1432 ShouldCheckConstantCond =
false;
1434 if (i != 0 && CaseVals[i].first == CaseVals[i-1].first) {
1437 StringRef PrevString, CurrString;
1440 if (
DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(PrevCase)) {
1441 PrevString = DeclRef->getDecl()->getName();
1443 if (
DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(CurrCase)) {
1444 CurrString = DeclRef->getDecl()->getName();
1447 CaseVals[i-1].first.toString(CaseValStr);
1449 if (PrevString == CurrString)
1450 Diag(CaseVals[i].second->getLHS()->getBeginLoc(),
1451 diag::err_duplicate_case)
1452 << (PrevString.empty() ? CaseValStr.str() : PrevString);
1454 Diag(CaseVals[i].second->getLHS()->getBeginLoc(),
1455 diag::err_duplicate_case_differing_expr)
1456 << (PrevString.empty() ? CaseValStr.str() : PrevString)
1457 << (CurrString.empty() ? CaseValStr.str() : CurrString)
1460 Diag(CaseVals[i - 1].second->getLHS()->getBeginLoc(),
1461 diag::note_duplicate_case_prev);
1464 CaseListIsErroneous =
true;
1471 if (!CaseRanges.empty()) {
1474 llvm::stable_sort(CaseRanges);
1477 std::vector<llvm::APSInt> HiVals;
1478 for (
unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {
1479 llvm::APSInt &LoVal = CaseRanges[i].first;
1480 CaseStmt *CR = CaseRanges[i].second;
1483 const Expr *HiBeforePromotion = Hi;
1490 CondWidthBeforePromotion, CondIsSignedBeforePromotion);
1496 if (LoVal > HiVal) {
1499 CaseRanges.erase(CaseRanges.begin()+i);
1505 if (ShouldCheckConstantCond &&
1506 LoVal <= ConstantCondValue &&
1507 ConstantCondValue <= HiVal)
1508 ShouldCheckConstantCond =
false;
1510 HiVals.push_back(HiVal);
1516 for (
unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {
1517 llvm::APSInt &CRLo = CaseRanges[i].first;
1518 llvm::APSInt &CRHi = HiVals[i];
1519 CaseStmt *CR = CaseRanges[i].second;
1524 llvm::APSInt OverlapVal(32);
1528 CaseValsTy::iterator I =
1529 llvm::lower_bound(CaseVals, CRLo, CaseCompareFunctor());
1530 if (I != CaseVals.end() && I->first < CRHi) {
1531 OverlapVal = I->first;
1532 OverlapStmt = I->second;
1536 I = std::upper_bound(I, CaseVals.end(), CRHi, CaseCompareFunctor());
1537 if (I != CaseVals.begin() && (I-1)->first >= CRLo) {
1538 OverlapVal = (I-1)->first;
1539 OverlapStmt = (I-1)->second;
1544 if (i && CRLo <= HiVals[i-1]) {
1545 OverlapVal = HiVals[i-1];
1546 OverlapStmt = CaseRanges[i-1].second;
1554 diag::note_duplicate_case_prev);
1557 CaseListIsErroneous =
true;
1563 if (!CaseListIsErroneous && !CaseListIsIncomplete &&
1564 ShouldCheckConstantCond) {
1567 Diag(CondExpr->
getExprLoc(), diag::warn_missing_case_for_condition)
1580 if (!CaseListIsErroneous && !CaseListIsIncomplete && !HasConstantCond &&
1589 llvm::APSInt Val = EDI->getInitVal();
1591 EnumVals.push_back(std::make_pair(Val, EDI));
1594 auto EI = EnumVals.begin(), EIEnd =
1595 std::unique(EnumVals.begin(), EnumVals.end(),
EqEnumVals);
1598 for (CaseValsTy::const_iterator CI = CaseVals.begin();
1599 CI != CaseVals.end(); CI++) {
1600 Expr *CaseExpr = CI->second->getLHS();
1604 << CondTypeBeforePromotion;
1608 EI = EnumVals.begin();
1609 for (CaseRangesTy::const_iterator RI = CaseRanges.begin();
1610 RI != CaseRanges.end(); RI++) {
1611 Expr *CaseExpr = RI->second->getLHS();
1615 << CondTypeBeforePromotion;
1618 RI->second->getRHS()->EvaluateKnownConstInt(
Context);
1621 CaseExpr = RI->second->getRHS();
1625 << CondTypeBeforePromotion;
1629 auto CI = CaseVals.begin();
1630 auto RI = CaseRanges.begin();
1631 bool hasCasesNotInSwitch =
false;
1635 for (EI = EnumVals.begin(); EI != EIEnd; EI++) {
1637 switch (EI->second->getAvailability()) {
1650 if (EI->second->hasAttr<UnusedAttr>())
1654 while (CI != CaseVals.end() && CI->first < EI->first)
1657 if (CI != CaseVals.end() && CI->first == EI->first)
1661 for (; RI != CaseRanges.end(); RI++) {
1663 RI->second->getRHS()->EvaluateKnownConstInt(
Context);
1665 if (EI->first <= Hi)
1669 if (RI == CaseRanges.end() || EI->first < RI->first) {
1670 hasCasesNotInSwitch =
true;
1671 UnhandledNames.push_back(EI->second->getDeclName());
1675 if (TheDefaultStmt && UnhandledNames.empty() && ED->
isClosedNonFlag())
1679 if (!UnhandledNames.empty()) {
1681 ? diag::warn_def_missing_case
1682 : diag::warn_missing_case)
1685 for (
size_t I = 0,
E = std::min(UnhandledNames.size(), (
size_t)3);
1687 DB << UnhandledNames[I];
1690 if (!hasCasesNotInSwitch)
1697 diag::warn_empty_switch_body);
1701 if (CaseListIsErroneous)
1724 const EnumDecl *ED = ET->getDecl();
1729 if (ED->
hasAttr<FlagEnumAttr>()) {
1741 llvm::APSInt Val = EDI->getInitVal();
1743 EnumVals.push_back(std::make_pair(Val, EDI));
1745 if (EnumVals.empty())
1748 EnumValsTy::iterator EIend =
1749 std::unique(EnumVals.begin(), EnumVals.end(),
EqEnumVals);
1752 EnumValsTy::const_iterator EI = EnumVals.begin();
1753 while (EI != EIend && EI->first < RhsVal)
1755 if (EI == EIend || EI->first != RhsVal) {
1770 auto CondVal = Cond.
get();
1771 CheckBreakContinueBinding(CondVal.second);
1773 if (CondVal.second &&
1774 !
Diags.
isIgnored(diag::warn_comma_operator, CondVal.second->getExprLoc()))
1775 CommaVisitor(*this).Visit(CondVal.second);
1777 if (isa<NullStmt>(Body))
1781 WhileLoc, LParenLoc, RParenLoc);
1788 assert(Cond &&
"ActOnDoStmt(): missing expression");
1790 CheckBreakContinueBinding(Cond);
1794 Cond = CondResult.
get();
1799 Cond = CondResult.
get();
1804 CommaVisitor(*this).Visit(Cond);
1806 return new (
Context)
DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen);
1817 DeclSetVector &Decls;
1823 DeclExtractor(
Sema &S, DeclSetVector &Decls,
1825 Inherited(S.Context),
1830 bool isSimple() {
return Simple; }
1839 void VisitStmt(
Stmt *S) { Simple =
false; }
1847 Visit(
E->getSubExpr());
1852 if (
E->getOpcode() == UO_Deref)
1855 Visit(
E->getSubExpr());
1859 Visit(
E->getCond());
1860 Visit(
E->getTrueExpr());
1861 Visit(
E->getFalseExpr());
1865 Visit(
E->getSubExpr());
1869 Visit(
E->getOpaqueValue()->getSourceExpr());
1870 Visit(
E->getFalseExpr());
1881 VarDecl *VD = dyn_cast<VarDecl>(
E->getDecl());
1898 DeclSetVector &Decls;
1904 DeclMatcher(
Sema &S, DeclSetVector &Decls,
Stmt *Statement) :
1905 Inherited(S.Context), Decls(Decls), FoundDecl(
false) {
1906 if (!Statement)
return;
1924 if (
E->getCastKind() == CK_LValueToRValue)
1925 CheckLValueToRValueCast(
E->getSubExpr());
1927 Visit(
E->getSubExpr());
1930 void CheckLValueToRValueCast(
Expr *
E) {
1933 if (isa<DeclRefExpr>(
E)) {
1938 Visit(CO->getCond());
1939 CheckLValueToRValueCast(CO->getTrueExpr());
1940 CheckLValueToRValueCast(CO->getFalseExpr());
1945 dyn_cast<BinaryConditionalOperator>(
E)) {
1946 CheckLValueToRValueCast(BCO->getOpaqueValue()->getSourceExpr());
1947 CheckLValueToRValueCast(BCO->getFalseExpr());
1955 if (
VarDecl *VD = dyn_cast<VarDecl>(
E->getDecl()))
1956 if (Decls.count(VD))
1964 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(S))
1966 Visit(OVE->getSourceExpr());
1972 bool FoundDeclInUse() {
return FoundDecl; }
1976 void CheckForLoopConditionalStatement(
Sema &S,
Expr *Second,
1979 if (!Second)
return;
1986 DeclSetVector Decls;
1988 DeclExtractor DE(S, Decls, Ranges);
1992 if (!DE.isSimple())
return;
1995 if (Decls.size() == 0)
return;
1998 for (
auto *VD : Decls)
2002 if (DeclMatcher(S, Decls, Second).FoundDeclInUse() ||
2003 DeclMatcher(S, Decls, Third).FoundDeclInUse() ||
2004 DeclMatcher(S, Decls, Body).FoundDeclInUse())
2008 if (Decls.size() > 4) {
2012 for (
auto *VD : Decls)
2016 for (
auto Range : Ranges)
2019 S.
Diag(Ranges.begin()->getBegin(), PDiag);
2024 bool ProcessIterationStmt(
Sema &S,
Stmt* Statement,
bool &Increment,
2026 if (
auto Cleanups = dyn_cast<ExprWithCleanups>(Statement))
2027 if (!Cleanups->cleanupsHaveSideEffects())
2030 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(Statement)) {
2031 switch (UO->getOpcode()) {
2032 default:
return false;
2042 DRE = dyn_cast<DeclRefExpr>(UO->getSubExpr());
2050 default:
return false;
2058 DRE = dyn_cast<DeclRefExpr>(
Call->getArg(0));
2070 bool InSwitch =
false;
2073 BreakContinueFinder(
Sema &S,
const Stmt* Body) :
2074 Inherited(S.Context) {
2081 ContinueLoc =
E->getContinueLoc();
2086 BreakLoc =
E->getBreakLoc();
2090 if (
const Stmt *
Init = S->getInit())
2092 if (
const Stmt *CondVar = S->getConditionVariableDeclStmt())
2094 if (
const Stmt *Cond = S->getCond())
2099 if (
const Stmt *Body = S->getBody())
2104 void VisitForStmt(
const ForStmt *S) {
2107 if (
const Stmt *
Init = S->getInit())
2111 void VisitWhileStmt(
const WhileStmt *) {
2116 void VisitDoStmt(
const DoStmt *) {
2124 if (
const Stmt *
Init = S->getInit())
2126 if (
const Stmt *
Range = S->getRangeStmt())
2128 if (
const Stmt *
Begin = S->getBeginStmt())
2130 if (
const Stmt *End = S->getEndStmt())
2137 if (
const Stmt *Element = S->getElement())
2139 if (
const Stmt *Collection = S->getCollection())
2143 bool ContinueFound() {
return ContinueLoc.
isValid(); }
2144 bool BreakFound() {
return BreakLoc.
isValid(); }
2155 void CheckForRedundantIteration(
Sema &S,
Expr *Third,
Stmt *Body) {
2157 if (!Body || !Third)
return;
2167 if (!LastStmt)
return;
2169 bool LoopIncrement, LastIncrement;
2172 if (!ProcessIterationStmt(S, Third, LoopIncrement, LoopDRE))
return;
2173 if (!ProcessIterationStmt(S, LastStmt, LastIncrement, LastDRE))
return;
2177 if (LoopIncrement != LastIncrement ||
2180 if (BreakContinueFinder(S, Body).ContinueFound())
return;
2183 << LastDRE->
getDecl() << LastIncrement;
2191void Sema::CheckBreakContinueBinding(
Expr *
E) {
2194 BreakContinueFinder BCFinder(*
this,
E);
2196 if (BCFinder.BreakFound() && BreakParent) {
2198 Diag(BCFinder.GetBreakLoc(), diag::warn_break_binds_to_switch);
2200 Diag(BCFinder.GetBreakLoc(), diag::warn_loop_ctrl_binds_to_inner)
2204 Diag(BCFinder.GetContinueLoc(), diag::warn_loop_ctrl_binds_to_inner)
2221 const Decl *NonVarSeen =
nullptr;
2222 bool VarDeclSeen =
false;
2223 for (
auto *DI : DS->decls()) {
2224 if (
VarDecl *VD = dyn_cast<VarDecl>(DI)) {
2227 Diag(DI->getLocation(), diag::err_non_local_variable_decl_in_for);
2228 DI->setInvalidDecl();
2230 }
else if (!NonVarSeen) {
2240 if (NonVarSeen && !VarDeclSeen)
2245 CheckBreakContinueBinding(Second.
get().second);
2246 CheckBreakContinueBinding(third.
get());
2248 if (!Second.
get().first)
2249 CheckForLoopConditionalStatement(*
this, Second.
get().second, third.
get(),
2251 CheckForRedundantIteration(*
this, third.
get(), Body);
2253 if (Second.
get().second &&
2255 Second.
get().second->getExprLoc()))
2256 CommaVisitor(*this).Visit(Second.
get().second);
2259 if (isa<NullStmt>(Body))
2264 Body, ForLoc, LParenLoc, RParenLoc);
2284 if (
Decl->getType()->isUndeducedType()) {
2296 if (!isa<InitListExpr>(
Init) &&
Init->getType()->isVoidType()) {
2301 Decl->getTypeSourceInfo()->getTypeLoc(),
Init, InitType, Info);
2311 Decl->setType(InitType);
2329enum BeginEndFunction {
2338void NoteForRangeBeginEndFunction(
Sema &SemaRef,
Expr *
E,
2339 BeginEndFunction BEF) {
2348 std::string Description;
2349 bool IsTemplate =
false;
2352 FunTmpl->getTemplateParameters(), *
D->getTemplateSpecializationArgs());
2356 SemaRef.
Diag(
Loc, diag::note_for_range_begin_end)
2357 << BEF << IsTemplate << Description <<
E->
getType();
2391 return Diag(InitStmt->
getBeginLoc(), diag::err_objc_for_range_init_stmt)
2397 assert(DS &&
"first part of for range not a decl stmt");
2424 const auto DepthStr = std::to_string(S->getDepth() / 2);
2426 VarDecl *RangeVar = BuildForRangeVarDecl(*
this, RangeLoc,
2428 std::string(
"__range") + DepthStr);
2430 diag::err_for_range_deduction_failure)) {
2445 ForLoc, CoawaitLoc, InitStmt, ColonLoc, RangeDecl.
get(),
2447 nullptr,
nullptr, DS, RParenLoc, Kind,
2448 LifetimeExtendTemps);
2471 ExprResult *EndExpr, BeginEndFunction *BEF) {
2481 auto BuildBegin = [&] {
2485 BeginMemberLookup, CandidateSet,
2486 BeginRange, BeginExpr);
2491 << ColonLoc << BEF_begin << BeginRange->
getType();
2504 diag::err_for_range_iter_deduction_failure)) {
2505 NoteForRangeBeginEndFunction(SemaRef, BeginExpr->
get(), *BEF);
2511 auto BuildEnd = [&] {
2515 EndMemberLookup, CandidateSet,
2520 << ColonLoc << BEF_end << EndRange->
getType();
2524 diag::err_for_range_iter_deduction_failure)) {
2525 NoteForRangeBeginEndFunction(SemaRef, EndExpr->
get(), *BEF);
2545 if (BeginMemberLookup.
empty() != EndMemberLookup.
empty()) {
2550 auto BuildNonmember = [&](
2560 switch (BuildFound()) {
2567 SemaRef.
PDiag(diag::err_for_range_invalid)
2568 << BeginRange->
getType() << BEFFound),
2575 diag::note_for_range_member_begin_end_ignored)
2576 << BeginRange->
getType() << BEFFound;
2580 llvm_unreachable(
"unexpected ForRangeStatus");
2582 if (BeginMemberLookup.
empty())
2583 return BuildNonmember(BEF_end, EndMemberLookup, BuildEnd, BuildBegin);
2584 return BuildNonmember(BEF_begin, BeginMemberLookup, BuildBegin, BuildEnd);
2621 S, ForLoc, CoawaitLoc, InitStmt, LoopVarDecl, ColonLoc,
2630 SemaRef.
Diag(RangeLoc, diag::err_for_range_dereference)
2633 S, ForLoc, CoawaitLoc, InitStmt, LoopVarDecl, ColonLoc,
2654 DeclStmt *RangeDS = cast<DeclStmt>(RangeDecl);
2658 DeclStmt *LoopVarDS = cast<DeclStmt>(LoopVarDecl);
2672 if (
auto *DD = dyn_cast<DecompositionDecl>(LoopVar))
2673 for (
auto *Binding : DD->bindings())
2677 }
else if (!BeginDeclStmt.
get()) {
2699 diag::err_for_range_incomplete_type))
2706 for (
auto *MTE : LifetimeExtendTemps)
2712 const auto DepthStr = std::to_string(S->getDepth() / 2);
2714 std::string(
"__begin") + DepthStr);
2716 std::string(
"__end") + DepthStr);
2727 BeginExpr = BeginRangeRef;
2734 diag::err_for_range_iter_deduction_failure)) {
2735 NoteForRangeBeginEndFunction(*
this, BeginExpr.
get(), BEF_begin);
2745 dyn_cast<VariableArrayType>(UnqAT)) {
2772 VAT->desugar(), RangeLoc))
2783 VAT->getElementType(), RangeLoc))
2791 SizeOfVLAExprR.
get(), SizeOfEachElementExprR.
get());
2798 llvm_unreachable(
"Unexpected array type in for-range");
2802 EndExpr =
ActOnBinOp(S, ColonLoc, tok::plus, EndRangeRef.
get(),
2807 diag::err_for_range_iter_deduction_failure)) {
2808 NoteForRangeBeginEndFunction(*
this, EndExpr.
get(), BEF_end);
2814 BeginEndFunction BEFFailure;
2816 *
this, BeginRangeRef.
get(), EndRangeRef.
get(), RangeType, BeginVar,
2817 EndVar, ColonLoc, CoawaitLoc, &CandidateSet, &BeginExpr, &EndExpr,
2821 BEFFailure == BEF_begin) {
2826 QualType ArrayTy = PVD->getOriginalType();
2827 QualType PointerTy = PVD->getType();
2829 Diag(
Range->getBeginLoc(), diag::err_range_on_array_parameter)
2830 << RangeLoc << PVD << ArrayTy << PointerTy;
2831 Diag(PVD->getLocation(), diag::note_declared_at);
2840 CoawaitLoc, InitStmt,
2841 LoopVarDecl, ColonLoc,
2853 PDiag(diag::err_for_range_invalid)
2854 << RangeLoc <<
Range->getType()
2864 "invalid range expression in for loop");
2871 ? diag::warn_for_range_begin_end_types_differ
2872 : diag::ext_for_range_begin_end_types_differ)
2873 << BeginType << EndType;
2874 NoteForRangeBeginEndFunction(*
this, BeginExpr.
get(), BEF_begin);
2875 NoteForRangeBeginEndFunction(*
this, EndExpr.
get(), BEF_end);
2895 NotEqExpr =
ActOnBinOp(S, ColonLoc, tok::exclaimequal,
2896 BeginRef.
get(), EndRef.
get());
2903 Diag(RangeLoc, diag::note_for_range_invalid_iterator)
2904 << RangeLoc << 0 << BeginRangeRef.
get()->
getType();
2905 NoteForRangeBeginEndFunction(*
this, BeginExpr.
get(), BEF_begin);
2907 NoteForRangeBeginEndFunction(*
this, EndExpr.
get(), BEF_end);
2918 if (!IncrExpr.isInvalid() && CoawaitLoc.
isValid())
2923 if (!IncrExpr.isInvalid())
2925 if (IncrExpr.isInvalid()) {
2926 Diag(RangeLoc, diag::note_for_range_invalid_iterator)
2927 << RangeLoc << 2 << BeginRangeRef.
get()->
getType() ;
2928 NoteForRangeBeginEndFunction(*
this, BeginExpr.
get(), BEF_begin);
2940 Diag(RangeLoc, diag::note_for_range_invalid_iterator)
2941 << RangeLoc << 1 << BeginRangeRef.
get()->
getType();
2942 NoteForRangeBeginEndFunction(*
this, BeginExpr.
get(), BEF_begin);
2952 NoteForRangeBeginEndFunction(*
this, BeginExpr.
get(), BEF_begin);
2967 InitStmt, RangeDS, cast_or_null<DeclStmt>(BeginDeclStmt.
get()),
2968 cast_or_null<DeclStmt>(EndDeclStmt.
get()), NotEqExpr.
get(),
2969 IncrExpr.get(), LoopVarDS,
nullptr, ForLoc, CoawaitLoc,
2970 ColonLoc, RParenLoc);
2989 if (
auto Cleanups = dyn_cast<ExprWithCleanups>(InitExpr))
2990 if (!Cleanups->cleanupsHaveSideEffects())
2991 InitExpr = Cleanups->getSubExpr();
2994 dyn_cast<MaterializeTemporaryExpr>(InitExpr);
3004 while (!isa<CXXOperatorCallExpr>(
E) && !isa<UnaryOperator>(
E)) {
3018 if (isa<UnaryOperator>(
E)) {
3025 ReferenceReturnType = ReturnType;
3028 if (!ReferenceReturnType.
isNull()) {
3033 diag::warn_for_range_const_ref_binds_temp_built_from_ref)
3034 << VD << VariableType << ReferenceReturnType;
3047 SemaRef.
Diag(VD->
getLocation(), diag::warn_for_range_ref_binds_ret_temp)
3048 << VD << RangeInitType;
3061 return RD->hasAttr<TrivialABIAttr>();
3078 if (!CE->getConstructor()->isCopyConstructor())
3080 }
else if (
const CastExpr *CE = dyn_cast<CastExpr>(InitExpr)) {
3081 if (CE->getCastKind() != CK_LValueToRValue)
3099 << VD << VariableType;
3120 diag::warn_for_range_const_ref_binds_temp_built_from_ref,
3147 ForStmt->getRangeInit()->getType());
3157 if (isa<ObjCForCollectionStmt>(S))
3164 diag::warn_empty_range_based_for_body);
3178 if (
getCurScope()->isInOpenACCComputeConstructScope())
3212 if (
getCurScope()->isInOpenACCComputeConstructScope())
3219 const Scope &DestScope) {
3222 S.
Diag(
Loc, diag::warn_jump_out_of_seh_finally);
3231 return StmtError(
Diag(ContinueLoc, diag::err_continue_not_in_loop));
3233 if (S->isConditionVarScope()) {
3237 return StmtError(
Diag(ContinueLoc, diag::err_continue_from_cond_var_init));
3243 if (S->isOpenACCComputeConstructScope())
3245 Diag(ContinueLoc, diag::err_acc_branch_in_out_compute_construct)
3258 return StmtError(
Diag(BreakLoc, diag::err_break_not_in_loop_or_switch));
3260 if (S->isOpenMPLoopScope())
3261 return StmtError(
Diag(BreakLoc, diag::err_omp_loop_cannot_use_stmt)
3271 if (S->isOpenACCComputeConstructScope() ||
3272 (S->isLoopScope() && S->getParent() &&
3273 S->getParent()->isOpenACCComputeConstructScope()))
3275 Diag(BreakLoc, diag::err_acc_branch_in_out_compute_construct)
3290 if (!DR || DR->refersToEnclosingVariableOrCapture())
3292 const auto *VD = dyn_cast<VarDecl>(DR->getDecl());
3315 if (VD->
getKind() == Decl::ParmVar)
3317 else if (VD->
getKind() != Decl::Var)
3330 if (VD->
hasAttr<BlocksAttr>())
3366 auto invalidNRVO = [&] {
3375 if ((ReturnType->
getTypeClass() == Type::TypeClass::Auto &&
3378 return invalidNRVO();
3384 return invalidNRVO();
3404 const auto *Step = llvm::find_if(
Seq.steps(), [](
const auto &Step) {
3405 return Step.Kind == InitializationSequence::SK_ConstructorInitialization ||
3406 Step.Kind == InitializationSequence::SK_UserConversion;
3408 if (Step !=
Seq.step_end()) {
3409 const auto *FD = Step->Function.Function;
3410 if (isa<CXXConstructorDecl>(FD)
3412 : cast<CXXMethodDecl>(FD)->getRefQualifier() ==
RQ_None)
3420 bool SupressSimplerImplicitMoves) {
3426 Expr *InitExpr = &AsRvalue;
3428 Value->getBeginLoc());
3430 auto Res =
Seq.getFailedOverloadResult();
3441 return Seq.Perform(*
this, Entity, Kind,
Value);
3461 bool SupressSimplerImplicitMoves) {
3469 bool HasDeducedReturnType =
3479 RetValExp = ER.
get();
3485 if (HasDeducedReturnType) {
3498 assert(AT &&
"lost auto type from lambda return type");
3510 if (RetValExp && !isa<InitListExpr>(RetValExp)) {
3514 RetValExp =
Result.get();
3529 Diag(ReturnLoc, diag::err_lambda_return_init_list)
3543 if (
auto *CurBlock = dyn_cast<BlockScopeInfo>(CurCap)) {
3545 Diag(ReturnLoc, diag::err_noreturn_block_has_return_expr);
3548 }
else if (
auto *CurRegion = dyn_cast<CapturedRegionScopeInfo>(CurCap)) {
3549 Diag(ReturnLoc, diag::err_return_in_captured_stmt) << CurRegion->getRegionName();
3552 assert(CurLambda &&
"unknown kind of captured scope");
3556 Diag(ReturnLoc, diag::err_noreturn_lambda_has_return_expr);
3568 if (RetValExp && !isa<InitListExpr>(RetValExp) &&
3574 Diag(ReturnLoc, diag::ext_return_has_void_expr) <<
"literal" << 2;
3576 Diag(ReturnLoc, diag::err_return_block_has_expr);
3577 RetValExp =
nullptr;
3580 }
else if (!RetValExp) {
3581 return StmtError(
Diag(ReturnLoc, diag::err_block_return_missing_expr));
3594 Entity, NRInfo, RetValExp, SupressSimplerImplicitMoves);
3599 RetValExp = Res.
get();
3600 CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc);
3608 RetValExp = ER.
get();
3622 if (
auto *CurBlock = dyn_cast<BlockScopeInfo>(CurCap);
3625 CurBlock->TheDecl->setInvalidDecl();
3645 LocalTypedefNameReferencer(
Sema &S) : S(S) {}
3646 bool VisitRecordType(
RecordType *RT)
override;
3651bool LocalTypedefNameReferencer::VisitRecordType(
RecordType *RT) {
3652 auto *R = dyn_cast<CXXRecordDecl>(RT->
getDecl());
3653 if (!R || !R->isLocalClass() || !R->isLocalClass()->isExternallyVisible() ||
3654 R->isDependentType())
3656 for (
auto *TmpD : R->decls())
3657 if (
auto *
T = dyn_cast<TypedefNameDecl>(TmpD))
3658 if (
T->getAccess() !=
AS_private || R->hasFriends())
3680 if (isa_and_nonnull<InitListExpr>(RetExpr)) {
3685 : diag::err_auto_fn_return_init_list)
3695 assert(AT->
isDeduced() &&
"should have deduced to dependent type");
3709 Diag(ReturnLoc, diag::err_auto_fn_return_void_but_not_auto)
3725 if (FindResult.Expression)
3726 TemplateSpecLoc = FindResult.Expression->getNameLoc();
3730 OrigResultType, RetExpr, Deduced, Info,
false,
3746 Diag(ReturnLoc, diag::err_typecheck_missing_return_type_incompatible)
3749 Diag(ReturnLoc, diag::err_auto_fn_different_deductions)
3764 LocalTypedefNameReferencer(*this).TraverseType(RetExpr->
getType());
3787 RetValExp,
nullptr,
true);
3791 if (
getCurScope()->isInOpenACCComputeConstructScope())
3793 Diag(ReturnLoc, diag::err_acc_branch_in_out_compute_construct)
3800 "first coroutine location not set");
3801 Diag(ReturnLoc, diag::err_return_in_coroutine);
3806 CheckInvalidBuiltinCountedByRef(RetVal.
get(), ReturnArgKind);
3814 const_cast<VarDecl *
>(cast<ReturnStmt>(R.
get())->getNRVOCandidate());
3838 bool AllowRecovery) {
3846 bool SupressSimplerImplicitMoves =
3854 SupressSimplerImplicitMoves);
3858 const AttrVec *Attrs =
nullptr;
3859 bool isObjCMethod =
false;
3866 Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr) << FD;
3867 if (FD->
isMain() && RetValExp)
3868 if (isa<CXXBoolLiteralExpr>(RetValExp))
3869 Diag(ReturnLoc, diag::warn_main_returns_bool_literal)
3871 if (FD->
hasAttr<CmseNSEntryAttr>() && RetValExp) {
3879 isObjCMethod =
true;
3893 const auto *ATy = dyn_cast<ArrayType>(RetValExp->
getType());
3894 if (ATy && ATy->getElementType().isWebAssemblyReferenceType()) {
3895 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
3909 RetValExp = ER.
get();
3935 AT->isDeduced() ? FnRetType :
QualType());
3936 if (Recovery.isInvalid())
3938 RetValExp = Recovery.get();
3954 if (
auto *ILE = dyn_cast<InitListExpr>(RetValExp)) {
3959 int FunctionKind = 0;
3960 if (isa<ObjCMethodDecl>(CurDecl))
3962 else if (isa<CXXConstructorDecl>(CurDecl))
3964 else if (isa<CXXDestructorDecl>(CurDecl))
3967 Diag(ReturnLoc, diag::err_return_init_list)
3971 RetValExp = AllowRecovery
3973 ILE->getRBraceLoc(), ILE->inits())
3978 unsigned D = diag::ext_return_has_expr;
3981 if (isa<CXXConstructorDecl>(CurDecl) ||
3982 isa<CXXDestructorDecl>(CurDecl))
3983 D = diag::err_ctor_dtor_returns_void;
3985 D = diag::ext_return_has_void_expr;
3992 RetValExp =
Result.get();
3997 if (
D == diag::err_ctor_dtor_returns_void) {
3999 Diag(ReturnLoc,
D) << CurDecl << isa<CXXDestructorDecl>(CurDecl)
4003 else if (
D != diag::ext_return_has_void_expr ||
4007 int FunctionKind = 0;
4008 if (isa<ObjCMethodDecl>(CurDecl))
4010 else if (isa<CXXConstructorDecl>(CurDecl))
4012 else if (isa<CXXDestructorDecl>(CurDecl))
4025 RetValExp = ER.
get();
4031 }
else if (!RetValExp && !HasDependentReturnType) {
4038 Diag(ReturnLoc, diag::err_constexpr_return_missing_expr)
4044 unsigned DiagID =
getLangOpts().C99 ? diag::ext_return_missing_expr
4045 : diag::warn_return_missing_expr;
4049 "Not in a FunctionDecl or ObjCMethodDecl?");
4050 bool IsMethod = FD ==
nullptr;
4053 Diag(ReturnLoc, DiagID) << ND << IsMethod;
4059 assert(RetValExp || HasDependentReturnType);
4060 QualType RetType = RelatedRetType.
isNull() ? FnRetType : RelatedRetType;
4073 Entity, NRInfo, RetValExp, SupressSimplerImplicitMoves);
4076 RetValExp->
getEndLoc(), RetValExp, RetType);
4087 if (!RelatedRetType.
isNull()) {
4098 CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc, isObjCMethod, Attrs,
4107 RetValExp = ER.
get();
4114 if (
Result->getNRVOCandidate())
4125 Stmt *HandlerBlock) {
4128 CXXCatchStmt(CatchLoc, cast_or_null<VarDecl>(ExDecl), HandlerBlock);
4132class CatchHandlerType {
4134 LLVM_PREFERRED_TYPE(
bool)
4135 unsigned IsPointer : 1;
4139 friend struct llvm::DenseMapInfo<CatchHandlerType>;
4140 enum Unique { ForDenseMap };
4141 CatchHandlerType(
QualType QT, Unique) : QT(QT), IsPointer(
false) {}
4159 CatchHandlerType(
QualType QT,
bool IsPointer)
4160 : QT(QT), IsPointer(IsPointer) {}
4162 QualType underlying()
const {
return QT; }
4163 bool isPointer()
const {
return IsPointer; }
4165 friend bool operator==(
const CatchHandlerType &LHS,
4166 const CatchHandlerType &RHS) {
4168 if (LHS.IsPointer != RHS.IsPointer)
4171 return LHS.QT == RHS.QT;
4177template <>
struct DenseMapInfo<CatchHandlerType> {
4179 return CatchHandlerType(DenseMapInfo<QualType>::getEmptyKey(),
4180 CatchHandlerType::ForDenseMap);
4184 return CatchHandlerType(DenseMapInfo<QualType>::getTombstoneKey(),
4185 CatchHandlerType::ForDenseMap);
4189 return DenseMapInfo<QualType>::getHashValue(
Base.underlying());
4193 const CatchHandlerType &RHS) {
4200class CatchTypePublicBases {
4201 const llvm::DenseMap<QualType, CXXCatchStmt *> &TypesToCheck;
4208 CatchTypePublicBases(
const llvm::DenseMap<QualType, CXXCatchStmt *> &
T,
4210 : TypesToCheck(
T), FoundHandler(nullptr), TestAgainstType(QT) {}
4212 CXXCatchStmt *getFoundHandler()
const {
return FoundHandler; }
4213 QualType getFoundHandlerType()
const {
return FoundHandlerType; }
4216 if (S->getAccessSpecifier() == AccessSpecifier::AS_public) {
4217 QualType Check = S->getType().getCanonicalType();
4218 const auto &M = TypesToCheck;
4219 auto I = M.find(Check);
4231 if (I->second->getCaughtType()->isPointerType() ==
4233 FoundHandler = I->second;
4234 FoundHandlerType = Check;
4247 const bool IsOpenMPGPUTarget =
4248 getLangOpts().OpenMPIsTargetDevice && (
T.isNVPTX() ||
T.isAMDGCN());
4251 if (!IsOpenMPGPUTarget && !
getLangOpts().CXXExceptions &&
4254 targetDiag(TryLoc, diag::err_exceptions_disabled) <<
"try";
4259 if (IsOpenMPGPUTarget)
4260 targetDiag(TryLoc, diag::warn_try_not_valid_on_target) <<
T.str();
4265 <<
"try" << llvm::to_underlying(
CUDA().CurrentTarget());
4268 Diag(TryLoc, diag::err_omp_simd_region_cannot_use_stmt) <<
"try";
4274 Diag(TryLoc, diag::err_mixing_cxx_try_seh_try) << 0;
4278 const unsigned NumHandlers = Handlers.size();
4279 assert(!Handlers.empty() &&
4280 "The parser shouldn't call this if there are no handlers.");
4282 llvm::DenseMap<QualType, CXXCatchStmt *> HandledBaseTypes;
4283 llvm::DenseMap<CatchHandlerType, CXXCatchStmt *> HandledTypes;
4284 for (
unsigned i = 0; i < NumHandlers; ++i) {
4291 if (i < NumHandlers - 1)
4305 QualType Underlying = HandlerCHT.underlying();
4307 if (!RD->hasDefinition())
4315 Paths.setOrigin(RD);
4316 CatchTypePublicBases CTPB(HandledBaseTypes,
4318 if (RD->lookupInBases(CTPB, Paths)) {
4320 if (!Paths.isAmbiguous(
4323 diag::warn_exception_caught_by_earlier_handler)
4326 diag::note_previous_exception_handler)
4338 auto R = HandledTypes.insert(
4343 diag::warn_exception_caught_by_earlier_handler)
4346 diag::note_previous_exception_handler)
4359 assert(TryBlock && Handler);
4386 Diag(TryLoc, diag::err_seh_try_outside_functions);
4390 Diag(TryLoc, diag::err_seh_try_unsupported);
4397 assert(FilterExpr &&
Block);
4401 Diag(FilterExpr->
getExprLoc(), diag::err_filter_expression_integral)
4423 Scope *SEHTryParent = CurScope;
4425 SEHTryParent = SEHTryParent->
getParent();
4440 QualifierLoc, NameInfo,
4441 cast<CompoundStmt>(Nested));
4458 unsigned NumParams) {
4476 assert(NumParams > 0 &&
"CapturedStmt requires context parameter");
4520 CaptureInits.push_back(
Init.get());
4527 unsigned NumParams) {
4558 unsigned OpenMPCaptureLevel) {
4564 bool ContextIsFound =
false;
4565 unsigned ParamNum = 0;
4568 I !=
E; ++I, ++ParamNum) {
4569 if (I->second.isNull()) {
4570 assert(!ContextIsFound &&
4571 "null type has been found already for '__context' parameter");
4581 ContextIsFound =
true;
4591 assert(ContextIsFound &&
"no null type for '__context' parameter");
4592 if (!ContextIsFound) {
4648 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::Record Record
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file declares semantic analysis for CUDA constructs.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis for OpenMP constructs and clauses.
static bool CmpEnumVals(const std::pair< llvm::APSInt, EnumConstantDecl * > &lhs, const std::pair< llvm::APSInt, EnumConstantDecl * > &rhs)
CmpEnumVals - Comparison predicate for sorting enumeration values.
static bool FinishForRangeVarDecl(Sema &SemaRef, VarDecl *Decl, Expr *Init, SourceLocation Loc, int DiagID)
Finish building a variable declaration for a for-range statement.
static bool CmpCaseVals(const std::pair< llvm::APSInt, CaseStmt * > &lhs, const std::pair< llvm::APSInt, CaseStmt * > &rhs)
CmpCaseVals - Comparison predicate for sorting case values.
SmallVector< std::pair< llvm::APSInt, EnumConstantDecl * >, 64 > EnumValsTy
static bool ShouldDiagnoseSwitchCaseNotInEnum(const Sema &S, const EnumDecl *ED, const Expr *CaseExpr, EnumValsTy::iterator &EI, EnumValsTy::iterator &EIEnd, const llvm::APSInt &Val)
Returns true if we should emit a diagnostic about this case expression not being a part of the enum u...
static bool DiagnoseUnusedComparison(Sema &S, const Expr *E)
Diagnose unused comparisons, both builtin and overloaded operators.
static bool EqEnumVals(const std::pair< llvm::APSInt, EnumConstantDecl * > &lhs, const std::pair< llvm::APSInt, EnumConstantDecl * > &rhs)
EqEnumVals - Comparison preficate for uniqing enumeration values.
static bool hasDeducedReturnType(FunctionDecl *FD)
Determine whether the declared return type of the specified function contains 'auto'.
static bool ObjCEnumerationCollection(Expr *Collection)
static void DiagnoseForRangeConstVariableCopies(Sema &SemaRef, const VarDecl *VD)
static StmtResult RebuildForRangeWithDereference(Sema &SemaRef, Scope *S, SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *InitStmt, Stmt *LoopVarDecl, SourceLocation ColonLoc, Expr *Range, SourceLocation RangeLoc, SourceLocation RParenLoc)
Speculatively attempt to dereference an invalid range expression.
static void checkEnumTypesInSwitchStmt(Sema &S, const Expr *Cond, const Expr *Case)
static void DiagnoseForRangeReferenceVariableCopies(Sema &SemaRef, const VarDecl *VD, QualType RangeInitType)
static void DiagnoseForRangeVariableCopies(Sema &SemaRef, const CXXForRangeStmt *ForStmt)
DiagnoseForRangeVariableCopies - Diagnose three cases and fixes for them.
static bool CheckSimplerImplicitMovesMSVCWorkaround(const Sema &S, const Expr *E)
static bool VerifyInitializationSequenceCXX98(const Sema &S, const InitializationSequence &Seq)
Verify that the initialization sequence that was picked for the first overload resolution is permissi...
static QualType GetTypeBeforeIntegralPromotion(const Expr *&E)
GetTypeBeforeIntegralPromotion - Returns the pre-promotion type of potentially integral-promoted expr...
static Sema::ForRangeStatus BuildNonArrayForRange(Sema &SemaRef, Expr *BeginRange, Expr *EndRange, QualType RangeType, VarDecl *BeginVar, VarDecl *EndVar, SourceLocation ColonLoc, SourceLocation CoawaitLoc, OverloadCandidateSet *CandidateSet, ExprResult *BeginExpr, ExprResult *EndExpr, BeginEndFunction *BEF)
Create the initialization, compare, and increment steps for the range-based for loop expression.
static bool hasTrivialABIAttr(QualType VariableType)
Determines whether the VariableType's declaration is a record with the clang::trivial_abi attribute.
static void AdjustAPSInt(llvm::APSInt &Val, unsigned BitWidth, bool IsSigned)
static bool buildCapturedStmtCaptureList(Sema &S, CapturedRegionScopeInfo *RSI, SmallVectorImpl< CapturedStmt::Capture > &Captures, SmallVectorImpl< Expr * > &CaptureInits)
static bool DiagnoseNoDiscard(Sema &S, const NamedDecl *OffendingDecl, const WarnUnusedResultAttr *A, SourceLocation Loc, SourceRange R1, SourceRange R2, bool IsCtor)
static void checkCaseValue(Sema &S, SourceLocation Loc, const llvm::APSInt &Val, unsigned UnpromotedWidth, bool UnpromotedSign)
Check the specified case value is in range for the given unpromoted switch type.
static void CheckJumpOutOfSEHFinally(Sema &S, SourceLocation Loc, const Scope &DestScope)
Defines the Objective-C statement AST node classes.
enum clang::format::@1325::AnnotatingParser::Context::@351 ContextType
Defines the clang::TypeLoc interface and its subclasses.
Allows QualTypes to be sorted and hence used in maps and sets.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
SourceManager & getSourceManager()
CharUnits getTypeAlignInChars(QualType T) const
Return the ABI-specified alignment of a (complete) type T, in characters.
unsigned getIntWidth(QualType T) const
QualType getObjCInterfaceType(const ObjCInterfaceDecl *Decl, ObjCInterfaceDecl *PrevDecl=nullptr) const
getObjCInterfaceType - Return the unique reference to the type for the specified ObjC interface decl.
QualType getAutoRRefDeductType() const
C++11 deduction pattern for 'auto &&' type.
QualType getTagDeclType(const TagDecl *Decl) const
Return the unique reference to the type for the specified TagDecl (struct/union/class/enum) decl.
bool hasSameType(QualType T1, QualType T2) const
Determine whether the given types T1 and T2 are equivalent.
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
QualType getTypeDeclType(const TypeDecl *Decl, const TypeDecl *PrevDecl=nullptr) const
Return the unique reference to the type for the specified type declaration.
QualType getPointerDiffType() const
Return the unique type for "ptrdiff_t" (C99 7.17) defined in <stddef.h>.
TypeSourceInfo * getTrivialTypeSourceInfo(QualType T, SourceLocation Loc=SourceLocation()) const
Allocate a TypeSourceInfo where all locations have been initialized to a given location,...
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
CharUnits getDeclAlign(const Decl *D, bool ForAlignof=false) const
Return a conservative estimate of the alignment of the specified decl D.
bool hasSameUnqualifiedType(QualType T1, QualType T2) const
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
bool hasSimilarType(QualType T1, QualType T2) const
Determine if two types are similar, according to the C++ rules.
const TargetInfo & getTargetInfo() const
QualType getAutoDeductType() const
C++11 deduction pattern for 'auto' type.
void adjustDeducedFunctionResultType(FunctionDecl *FD, QualType ResultType)
Change the result type of a function type once it is deduced.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Attr - This represents one attribute.
SourceLocation getLocation() const
SourceRange getRange() const
static AttributedStmt * Create(const ASTContext &C, SourceLocation Loc, ArrayRef< const Attr * > Attrs, Stmt *SubStmt)
Represents a C++11 auto or C++14 decltype(auto) type, possibly constrained by a type-constraint.
bool isDecltypeAuto() const
BinaryConditionalOperator - The GNU extension to the conditional operator which allows the middle ope...
A builtin binary operation expression such as "x + y" or "x <= y".
BreakStmt - This represents a break.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
Represents a path from a specific derived class (which is not represented as part of the path) to a p...
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
Represents a base class of a C++ class.
Represents binding an expression to a temporary.
A boolean literal, per ([C++ lex.bool] Boolean literals).
CXXCatchStmt - This represents a C++ catch block.
SourceLocation getBeginLoc() const LLVM_READONLY
VarDecl * getExceptionDecl() const
QualType getCaughtType() const
Represents a call to a C++ constructor.
Represents a C++ constructor within a class.
Represents a C++ conversion function within a class.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
Represents an explicit C++ type conversion that uses "functional" notation (C++ [expr....
Represents a call to a member function that may be written either with member call syntax (e....
Represents a static or instance method of a struct/union/class.
A call to an overloaded operator written using operator syntax.
Represents a C++ struct/union/class.
static CXXRecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl=nullptr, bool DelayTypeCreation=false)
An expression "T()" which creates an rvalue of a non-class type T.
Represents a C++ nested-name-specifier or a global scope specifier.
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context.
static CXXTryStmt * Create(const ASTContext &C, SourceLocation tryLoc, CompoundStmt *tryBlock, ArrayRef< Stmt * > handlers)
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
static CanQual< Type > CreateUnsafe(QualType Other)
Builds a canonical type from a QualType.
QualType withConst() const
Retrieves a version of this type with const applied.
Represents the body of a CapturedStmt, and serves as its DeclContext.
static DeclContext * castToDeclContext(const CapturedDecl *D)
void setContextParam(unsigned i, ImplicitParamDecl *P)
void setParam(unsigned i, ImplicitParamDecl *P)
static CapturedDecl * Create(ASTContext &C, DeclContext *DC, unsigned NumParams)
Describes the capture of either a variable, or 'this', or variable-length array type.
This captures a statement into a function.
Stmt * getCapturedStmt()
Retrieve the statement being captured.
static CapturedStmt * Create(const ASTContext &Context, Stmt *S, CapturedRegionKind Kind, ArrayRef< Capture > Captures, ArrayRef< Expr * > CaptureInits, CapturedDecl *CD, RecordDecl *RD)
CaseStmt - Represent a case statement.
static CaseStmt * Create(const ASTContext &Ctx, Expr *lhs, Expr *rhs, SourceLocation caseLoc, SourceLocation ellipsisLoc, SourceLocation colonLoc)
Build a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CompoundStmt - This represents a group of statements like { stmt stmt }.
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
ConditionalOperator - The ?: ternary operator.
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
Represents the canonical version of C arrays with a specified constant size.
ContinueStmt - This represents a continue.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isFileContext() const
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
void addDecl(Decl *D)
Add the declaration D into this context.
bool isStdNamespace() const
bool isFunctionOrMethod() const
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
bool isSingleDecl() const
A reference to a declared variable, function, enum, etc.
SourceLocation getLocation() const
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
const Decl * getSingleDecl() const
SourceLocation getBeginLoc() const LLVM_READONLY
Decl - This represents one declaration (or definition), e.g.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
static Decl * castFromDeclContext(const DeclContext *)
bool isInvalidDecl() const
SourceLocation getLocation() const
void setImplicit(bool I=true)
void setLocation(SourceLocation L)
DeclContext * getDeclContext()
SourceLocation getTypeSpecEndLoc() const
SourceLocation getTypeSpecStartLoc() const
SourceLocation getBeginLoc() const LLVM_READONLY
TypeSourceInfo * getTypeSourceInfo() const
QualType getDeducedType() const
Get the type deduced for this placeholder type, or null if it has not been deduced.
SourceLocation getDefaultLoc() const
DiagnosticBuilder Report(SourceLocation Loc, unsigned DiagID)
Issue the message to the client.
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
DoStmt - This represents a 'do/while' stmt.
Recursive AST visitor that supports extension via dynamic dispatch.
enumerator_range enumerators() const
bool isClosed() const
Returns true if this enum is either annotated with enum_extensibility(closed) or isn't annotated with...
bool isClosedNonFlag() const
Returns true if this enum is annotated with neither flag_enum nor enum_extensibility(open).
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of enums.
EnumDecl * getDecl() const
EvaluatedExprVisitor - This class visits 'Expr *'s.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isUnusedResultAWarning(const Expr *&WarnExpr, SourceLocation &Loc, SourceRange &R1, SourceRange &R2, ASTContext &Ctx) const
isUnusedResultAWarning - Return true if this immediate expression should be warned about if the resul...
bool isValueDependent() const
Determines whether the value of this expression depends on.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx, SmallVectorImpl< PartialDiagnosticAt > *Diag=nullptr) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors, e.g.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Decl * getReferencedDeclOfCallee()
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
bool isIntegerConstantExpr(const ASTContext &Ctx, SourceLocation *Loc=nullptr) const
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isKnownToHaveBooleanValue(bool Semantic=true) const
isKnownToHaveBooleanValue - Return true if this is an integer expression that is known to return 0 or...
Represents difference between two FPOptions values.
FPOptionsOverride getChangesFrom(const FPOptions &Base) const
Return difference with the given option set.
Represents a member of a struct/union/class.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
SourceLocation getRParenLoc() const
SourceLocation getBeginLoc() const
FullExpr - Represents a "full-expression" node.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
void setUsesSEHTry(bool UST)
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
QualType getReturnType() const
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isMain() const
Determines whether this function is "main", which is the entry point into an executable program.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isOverloadedOperator() const
Whether this function declaration represents an C++ overloaded operator, e.g., "operator+".
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
Represents a prototype with parameter type info, e.g.
Declaration of a template function.
FunctionType - C99 6.7.5.3 - Function Declarators.
static StringRef getNameForCallConv(CallingConv CC)
bool getNoReturnAttr() const
Determine whether this function type includes the GNU noreturn attribute.
QualType getReturnType() const
GNUNullExpr - Implements the GNU __null extension, which is a name for a null pointer constant that h...
GotoStmt - This represents a direct goto.
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static IfStmt * Create(const ASTContext &Ctx, SourceLocation IL, IfStatementKind Kind, Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LPL, SourceLocation RPL, Stmt *Then, SourceLocation EL=SourceLocation(), Stmt *Else=nullptr)
Create an IfStmt.
ImaginaryLiteral - We support imaginary integer and floating point literals, like "1....
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
IndirectGotoStmt - This represents an indirect goto.
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
Describes an entity that is being initialized.
static InitializedEntity InitializeResult(SourceLocation ReturnLoc, QualType Type)
Create the initialization entity for the result of a function.
static InitializedEntity InitializeRelatedResult(ObjCMethodDecl *MD, QualType Type)
Create the initialization entity for a related result.
unsigned allocateManglingNumber() const
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Represents the declaration of a label.
void setLocStart(SourceLocation L)
LabelStmt * getStmt() const
void setStmt(LabelStmt *T)
bool isMSAsmLabel() const
LabelStmt - Represents a label, which has a substatement.
Represents the results of name lookup.
bool empty() const
Return true if no decls were found.
Representation of a Microsoft __if_exists or __if_not_exists statement with a dependent name.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
A pointer to member type per C++ 8.3.3 - Pointers to members.
This represents a decl that may have a name.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const
Determine if the declaration obeys the reserved identifier rules of the given language.
A C++ nested-name-specifier augmented with source location information.
NullStmt - This is the null statement ";": C99 6.8.3p3.
Represents Objective-C's collection statement.
An expression that sends a message to the given Objective-C object or class.
ObjCMethodDecl - Represents an instance or class method declaration.
bool hasRelatedResultType() const
Determine whether this method has a result type that is related to the message receiver's type.
QualType getReturnType() const
ObjCInterfaceDecl * getClassInterface()
Represents a pointer to an Objective C object.
Wrapper for void* pointer.
void * getAsOpaquePtr() const
OverloadCandidateSet - A set of overload candidates, used in C++ overload resolution (C++ 13....
@ CSK_Normal
Normal lookup.
void NoteCandidates(PartialDiagnosticAt PA, Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef< Expr * > Args, StringRef Opc="", SourceLocation Loc=SourceLocation(), llvm::function_ref< bool(OverloadCandidate &)> Filter=[](OverloadCandidate &) { return true;})
When overload resolution fails, prints diagnostic messages containing the candidates in the candidate...
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
ParsedAttributes - A collection of parsed attributes.
Wrapper for source info for pointers.
SourceLocation getStarLoc() const
IdentifierTable & getIdentifierTable()
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType withRestrict() const
QualType withConst() const
bool isTriviallyCopyConstructibleType(const ASTContext &Context) const
Return true if this is a trivially copyable type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool isConstQualified() const
Determine whether this type is const-qualified.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Represents a struct/union/class.
static RecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl *PrevDecl=nullptr)
bool isOrContainsUnion() const
Returns whether this record is a union, or contains (at any nesting level) a union member.
virtual void completeDefinition()
Note that the definition of this type is now complete.
void setCapturedRecord()
Mark the record as a record for captured variables in CapturedStmt construct.
A helper class that allows the use of isa/cast/dyncast to detect TagType objects of structs/unions/cl...
RecordDecl * getDecl() const
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
void setRetValue(Expr *E)
static ReturnStmt * Create(const ASTContext &Ctx, SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
Create a return statement.
static SEHExceptStmt * Create(const ASTContext &C, SourceLocation ExceptLoc, Expr *FilterExpr, Stmt *Block)
static SEHFinallyStmt * Create(const ASTContext &C, SourceLocation FinallyLoc, Stmt *Block)
Represents a __leave statement.
static SEHTryStmt * Create(const ASTContext &C, bool isCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)
Scope - A scope is a transient data structure that is used while parsing the program.
const Scope * getFnParent() const
getFnParent - Return the closest scope that is a function body.
bool Contains(const Scope &rhs) const
Returns if rhs has a higher scope depth than this.
unsigned getFlags() const
getFlags - Return the flags for this scope.
Scope * getContinueParent()
getContinueParent - Return the closest scope that a continue statement would be affected by.
bool isSEHTryScope() const
Determine whether this scope is a SEH '__try' block.
Scope * getBreakParent()
getBreakParent - Return the closest scope that a break statement would be affected by.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
void updateNRVOCandidate(VarDecl *VD)
@ SwitchScope
This is a scope that corresponds to a switch statement.
A generic diagnostic builder for errors which may or may not be deferred.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID, bool DeferHint=false)
Emit a diagnostic.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
SemaDiagnosticBuilder DiagIfDeviceCode(SourceLocation Loc, unsigned DiagID)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as device c...
StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, Stmt *First, Expr *collection, SourceLocation RParenLoc)
StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body)
FinishObjCForCollectionStmt - Attach the body to a objective-C foreach statement.
bool inferObjCARCLifetime(ValueDecl *decl)
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable,...
void setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, unsigned Level)
Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) for FD based on DSA for the...
std::pair< VarDecl *, Expr * > get() const
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
Sema - This implements semantic analysis and AST building for C.
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)
Package the given type and TSI into a ParsedType.
SmallVector< Scope *, 2 > CurrentSEHFinally
Stack of active SEH __finally scopes. Can be empty.
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
Scope * getCurScope() const
Retrieve the parser's current scope.
void DiagnoseDiscardedExprMarkedNodiscard(const Expr *E)
DiagnoseDiscardedExprMarkedNodiscard - Given an expression that is semantically a discarded-value exp...
void ProcessStmtAttributes(Stmt *Stmt, const ParsedAttributes &InAttrs, SmallVectorImpl< const Attr * > &OutAttrs)
Process the attributes before creating an attributed statement.
ExprResult ActOnUnaryOp(Scope *S, SourceLocation OpLoc, tok::TokenKind Op, Expr *Input, bool IsAfterAmp=false)
Unary Operators. 'Tok' is the token for the operator.
StmtResult BuildMSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, NestedNameSpecifierLoc QualifierLoc, DeclarationNameInfo NameInfo, Stmt *Nested)
ExprResult IgnoredValueConversions(Expr *E)
IgnoredValueConversions - Given that an expression's result is syntactically ignored,...
@ LookupMemberName
Member name lookup, which finds the names of class/struct/union members.
bool ActOnCoroutineBodyStart(Scope *S, SourceLocation KwLoc, StringRef Keyword)
StmtResult BuildAttributedStmt(SourceLocation AttrsLoc, ArrayRef< const Attr * > Attrs, Stmt *SubStmt)
StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope)
StmtResult ActOnForEachLValueExpr(Expr *E)
In an Objective C collection iteration statement: for (x in y) x can be an arbitrary l-value expressi...
void ActOnForEachDeclStmt(DeclGroupPtrTy Decl)
void PushExpressionEvaluationContext(ExpressionEvaluationContext NewContext, Decl *LambdaContextDecl=nullptr, ExpressionEvaluationContextRecord::ExpressionKind Type=ExpressionEvaluationContextRecord::EK_Other)
ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, bool IsConstexpr=false)
CheckBooleanCondition - Diagnose problems involving the use of the given expression as a boolean cond...
@ Switch
An integral condition for a 'switch' statement.
SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes
Stack containing information about each of the nested function, block, and method scopes that are cur...
PoppedFunctionScopePtr PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP=nullptr, const Decl *D=nullptr, QualType BlockType=QualType())
Pop a function (or block or lambda or captured region) scope from the stack.
bool checkAndRewriteMustTailAttr(Stmt *St, const Attr &MTA)
Check whether the given statement can have musttail applied to it, issuing a diagnostic and returning...
StmtResult ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, LabelDecl *TheDecl)
StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, Scope *CurScope)
void setFunctionHasBranchIntoScope()
ExprResult ActOnCaseExpr(SourceLocation CaseLoc, ExprResult Val)
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, AllowFoldKind CanFold=NoFold)
VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...
StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue=true)
FieldDecl * BuildCaptureField(RecordDecl *RD, const sema::Capture &Capture)
Build a FieldDecl suitable to hold the given capture.
StmtResult BuildIfStmt(SourceLocation IfLoc, IfStatementKind StatementKind, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc, Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal)
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
ExprResult UsualUnaryConversions(Expr *E)
UsualUnaryConversions - Performs various conversions that are common to most operators (C99 6....
void DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc)
Look for instances where it is likely the comma operator is confused with another operator.
ExprResult CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond)
bool DiagIfReachable(SourceLocation Loc, ArrayRef< const Stmt * > Stmts, const PartialDiagnostic &PD)
Conditionally issue a diagnostic based on the statements's reachability analysis.
void FinalizeDeclaration(Decl *D)
FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...
void ActOnCapturedRegionError()
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ASTContext & getASTContext() const
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
void PopExpressionEvaluationContext()
StmtResult ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
ObjCMethodDecl * getCurMethodDecl()
getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, llvm::APSInt &Value, CCEKind CCE)
void setFunctionHasIndirectGoto()
ExprResult BuildCaptureInit(const sema::Capture &Capture, SourceLocation ImplicitCaptureLoc, bool IsOpenMPMapping=false)
Initialize the given capture with a suitable expression.
StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, Stmt *Body)
NamedReturnInfo getNamedReturnInfo(Expr *&E, SimplerImplicitMoveMode Mode=SimplerImplicitMoveMode::Normal)
Determine whether the given expression might be move-eligible or copy-elidable in either a (co_)retur...
std::unique_ptr< sema::FunctionScopeInfo, PoppedFunctionScopeDeleter > PoppedFunctionScopePtr
void DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID)
DiagnoseUnusedExprResult - If the statement passed in is an expression whose result is unused,...
FPOptions & getCurFPFeatures()
@ UPPC_Expression
An arbitrary expression.
const LangOptions & getLangOpts() const
StmtResult ActOnWhileStmt(SourceLocation WhileLoc, SourceLocation LParenLoc, ConditionResult Cond, SourceLocation RParenLoc, Stmt *Body)
bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, UnexpandedParameterPackContext UPPC)
If the given type contains an unexpanded parameter pack, diagnose the error.
const LangOptions & LangOpts
sema::LambdaScopeInfo * getCurLambda(bool IgnoreNonLambdaCapturingScope=false)
Retrieve the current lambda scope info, if any.
void ActOnStartOfCompoundStmt(bool IsStmtExpr)
bool DeduceFunctionTypeFromReturnExpr(FunctionDecl *FD, SourceLocation ReturnLoc, Expr *RetExpr, const AutoType *AT)
Deduce the return type for a function from a returned expression, per C++1y [dcl.spec....
void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool MightBeOdrUse)
Perform marking for a reference to an arbitrary declaration.
TypeLoc getReturnTypeLoc(FunctionDecl *FD) const
StmtResult ActOnExprStmtError()
const VarDecl * getCopyElisionCandidate(NamedReturnInfo &Info, QualType ReturnType)
Updates given NamedReturnInfo's move-eligible and copy-elidable statuses, considering the function re...
NamedDecl * getCurFunctionOrMethodDecl() const
getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...
StmtResult ActOnNullStmt(SourceLocation SemiLoc, bool HasLeadingEmptyMacro=false)
RecordDecl * CreateCapturedStmtRecordDecl(CapturedDecl *&CD, SourceLocation Loc, unsigned NumParams)
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams)
sema::FunctionScopeInfo * getCurFunction() const
void PushCompoundScope(bool IsStmtExpr)
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)
BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...
AssignConvertType CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, bool Diagnose=true, bool DiagnoseCFAudited=false, bool ConvertRHS=true)
Check assignment constraints for an assignment of RHS to LHSType.
void DiagnoseAssignmentEnum(QualType DstType, QualType SrcType, Expr *SrcExpr)
DiagnoseAssignmentEnum - Warn if assignment to enum is a constant integer not in the range of enum va...
ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E)
std::optional< sema::TemplateDeductionInfo * > isSFINAEContext() const
Determines whether we are currently in a context where template argument substitution failures are no...
bool findMacroSpelling(SourceLocation &loc, StringRef name)
Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...
void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, const Stmt *Body, unsigned DiagID)
Emit DiagID if statement located on StmtLoc has a suspicious null statement as a Body,...
void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody)
Warn if a for/while loop statement S, which is followed by PossibleBody, has a suspicious null statem...
ExprResult DefaultLvalueConversion(Expr *E)
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name)
Retrieves the declaration name from a parsed unqualified-id.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
StmtResult ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, NamedReturnInfo &NRInfo, bool SupressSimplerImplicitMoves)
ActOnCapScopeReturnStmt - Utility routine to type-check return statements for capturing scopes.
AssignConvertType
AssignConvertType - All of the 'assignment' semantic checks return this enum to indicate whether the ...
StmtResult ActOnCapturedRegionEnd(Stmt *S)
StmtResult ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, Stmt *First, ConditionResult Second, FullExprArg Third, SourceLocation RParenLoc, Stmt *Body)
StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, Expr *DestExp)
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
SourceManager & getSourceManager() const
ExprResult PerformMoveOrCopyInitialization(const InitializedEntity &Entity, const NamedReturnInfo &NRInfo, Expr *Value, bool SupressSimplerImplicitMoves=false)
Perform the initialization of a potentially-movable value, which is the result of return value.
void ActOnInitializerError(Decl *Dcl)
ActOnInitializerError - Given that there was an error parsing an initializer for the given declaratio...
StmtResult ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *InitStmt, Stmt *LoopVar, SourceLocation ColonLoc, Expr *Collection, SourceLocation RParenLoc, BuildForRangeKind Kind, ArrayRef< MaterializeTemporaryExpr * > LifetimeExtendTemps={})
ActOnCXXForRangeStmt - Check and build a C++11 for-range statement.
StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, bool AllowRecovery=false)
ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr)
Binary Operators. 'Tok' is the token for the operator.
void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD, RecordDecl *RD, CapturedRegionKind K, unsigned OpenMPCaptureLevel=0)
void setFunctionHasMustTail()
void setFunctionHasBranchProtectedScope()
StmtResult ActOnFinishSEHFinallyBlock(SourceLocation Loc, Stmt *Block)
StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope)
@ CCEK_CaseValue
Expression in a case label.
StmtResult BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *InitStmt, SourceLocation ColonLoc, Stmt *RangeDecl, Stmt *Begin, Stmt *End, Expr *Cond, Expr *Inc, Stmt *LoopVarDecl, SourceLocation RParenLoc, BuildForRangeKind Kind, ArrayRef< MaterializeTemporaryExpr * > LifetimeExtendTemps={})
BuildCXXForRangeStmt - Build or instantiate a C++11 for-range statement.
StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, SourceLocation WhileLoc, SourceLocation CondLParen, Expr *Cond, SourceLocation CondRParen)
StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc)
StmtResult ActOnMSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, CXXScopeSpec &SS, UnqualifiedId &Name, Stmt *Nested)
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ ImmediateFunctionContext
In addition of being constant evaluated, the current expression occurs in an immediate function conte...
StmtResult ActOnSEHExceptBlock(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)
void ActOnAfterCompoundStatementLeadingPragmas()
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl, ArrayRef< Decl * > Fields, SourceLocation LBrac, SourceLocation RBrac, const ParsedAttributesView &AttrList)
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
void DiscardCleanupsInEvaluationContext()
SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts
A stack of expression evaluation contexts.
void PushDeclContext(Scope *S, DeclContext *DC)
Set the current declaration context until it gets popped.
StmtResult ActOnAttributedStmt(const ParsedAttributes &AttrList, Stmt *SubStmt)
SourceManager & SourceMgr
DiagnosticsEngine & Diags
StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope)
void ActOnStartSEHFinallyBlock()
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void ActOnAbortSEHFinallyBlock()
QualType SubstAutoTypeDependent(QualType TypeWithAuto)
@ BFRK_Check
Determining whether a for-range statement could be built.
@ BFRK_Build
Initial building of a for-range statement.
@ BFRK_Rebuild
Instantiation or recovery rebuild of a for-range statement.
StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl, Stmt *HandlerBlock)
ActOnCXXCatchBlock - Takes an exception declaration and a handler block and creates a proper catch ha...
void ActOnCaseStmtBody(Stmt *CaseStmt, Stmt *SubStmt)
ActOnCaseStmtBody - This installs a statement as the body of a case.
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
bool DiagnoseAssignmentResult(AssignConvertType ConvTy, SourceLocation Loc, QualType DstType, QualType SrcType, Expr *SrcExpr, AssignmentAction Action, bool *Complained=nullptr)
DiagnoseAssignmentResult - Emit a diagnostic, if required, for the assignment conversion type specifi...
SemaDiagnosticBuilder targetDiag(SourceLocation Loc, unsigned DiagID, const FunctionDecl *FD=nullptr)
ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, ArrayRef< Expr * > SubExprs, QualType T=QualType())
Attempts to produce a RecoveryExpr after some AST node cannot be created.
StmtResult ActOnIfStmt(SourceLocation IfLoc, IfStatementKind StatementKind, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc, Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal)
std::string getTemplateArgumentBindingsText(const TemplateParameterList *Params, const TemplateArgumentList &Args)
Produces a formatted string that describes the binding of template parameters to template arguments.
ExprResult ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, bool IsType, void *TyOrEx, SourceRange ArgRange)
ActOnUnaryExprOrTypeTraitExpr - Handle sizeof(type) and sizeof expr and the same for alignof and __al...
ForRangeStatus BuildForRangeBeginEndCall(SourceLocation Loc, SourceLocation RangeLoc, const DeclarationNameInfo &NameInfo, LookupResult &MemberLookup, OverloadCandidateSet *CandidateSet, Expr *Range, ExprResult *CallExpr)
Build a call to 'begin' or 'end' for a C++11 for-range statement.
sema::CompoundScopeInfo & getCurCompoundScope() const
TemplateDeductionResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *Initializer, QualType &Result, sema::TemplateDeductionInfo &Info, bool DependentDeduction=false, bool IgnoreConstraints=false, TemplateSpecCandidateSet *FailedTSC=nullptr)
Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6)
void ActOnFinishOfCompoundStmt()
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)
bool IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, bool AllowMask) const
IsValueInFlagEnum - Determine if a value is allowed as part of a flag enum.
StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, SourceLocation ColonLoc, Stmt *SubStmt)
StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, ArrayRef< Stmt * > Handlers)
ActOnCXXTryBlock - Takes a try compound-statement and a number of handlers and creates a try statemen...
StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, Stmt *SubStmt, Scope *CurScope)
StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHS, SourceLocation DotDotDotLoc, ExprResult RHS, SourceLocation ColonLoc)
StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body)
FinishCXXForRangeStmt - Attach the body to a C++0x for-range statement.
ExprResult CorrectDelayedTyposInExpr(Expr *E, VarDecl *InitDecl=nullptr, bool RecoverUncorrectedTypos=false, llvm::function_ref< ExprResult(Expr *)> Filter=[](Expr *E) -> ExprResult { return E;})
Process any TypoExprs in the given Expr and its children, generating diagnostics as appropriate and r...
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
SourceLocation getLocWithOffset(IntTy Offset) const
Return a source location with the specified offset from this SourceLocation.
bool isMacroBodyExpansion(SourceLocation Loc) const
Tests whether the given source location represents the expansion of a macro body.
bool isInSystemMacro(SourceLocation loc) const
Returns whether Loc is expanded from a macro in a system header.
bool isInSystemHeader(SourceLocation Loc) const
Returns if a SourceLocation is in a system header.
A trivial tuple used to represent a source range.
SourceLocation getBegin() const
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
static std::tuple< bool, const Attr *, const Attr * > determineLikelihoodConflict(const Stmt *Then, const Stmt *Else)
static const Attr * getLikelihoodAttr(const Stmt *S)
SourceLocation getBeginLoc() const LLVM_READONLY
const SwitchCase * getNextSwitchCase() const
SwitchStmt - This represents a 'switch' stmt.
static SwitchStmt * Create(const ASTContext &Ctx, Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LParenLoc, SourceLocation RParenLoc)
Create a switch statement.
SwitchCase * getSwitchCaseList()
void setAllEnumCasesCovered()
Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a switch over an enum value then ...
Represents the declaration of a struct/union/class/enum.
bool isCompleteDefinition() const
Return true if this decl has its body fully specified.
TypedefNameDecl * getTypedefNameForAnonDecl() const
void startDefinition()
Starts the definition of this tag declaration.
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
bool isSEHTrySupported() const
Whether the target supports SEH __try.
TemplateSpecCandidateSet - A set of generalized overload candidates, used in template specializations...
void NoteCandidates(Sema &S, SourceLocation Loc)
NoteCandidates - When no template specialization match is found, prints diagnostic messages containin...
Base wrapper for a particular "section" of type source info.
QualType getType() const
Get the type for which this source info wrapper provides information.
T castAs() const
Convert to the specified TypeLoc type, asserting that this TypeLoc is of the desired type.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isRValueReferenceType() const
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<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.
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isObjectType() const
Determine whether this type is an object type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
TypeClass getTypeClass() const
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represents a C++ unqualified-id that has been parsed.
void setType(QualType newType)
Represents a variable declaration or definition.
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool isExceptionVariable() const
Determine whether this variable is the exception variable in a C++ catch statememt or an Objective-C ...
const Expr * getInit() const
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
bool hasDependentAlignment() const
Determines if this variable's alignment is dependent.
Represents a C array with a specified size that is not an integer-constant-expression.
WhileStmt - This represents a 'while' stmt.
static WhileStmt * Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, Stmt *Body, SourceLocation WL, SourceLocation LParenLoc, SourceLocation RParenLoc)
Create a while statement.
ValueDecl * getVariable() const
bool isVariableCapture() const
SourceLocation getLocation() const
Retrieve the location at which this variable was captured.
bool isVLATypeCapture() const
bool isThisCapture() const
bool isReferenceCapture() const
Retains information about a captured region.
unsigned short OpenMPLevel
unsigned short CapRegionKind
The kind of captured region.
RecordDecl * TheRecordDecl
The captured record type.
CapturedDecl * TheCapturedDecl
The CapturedDecl for this statement.
QualType ReturnType
ReturnType - The target type of return statements in this context, or null if unknown.
SmallVector< Capture, 4 > Captures
Captures - The captures.
bool HasImplicitReturnType
Contains information about the compound statement currently being parsed.
FPOptions InitialFPFeatures
FP options at the beginning of the compound statement, prior to any pragma.
void setHasEmptyLoopBodies()
Retains information about a function, method, or block that is currently being parsed.
llvm::PointerIntPair< SwitchStmt *, 1, bool > SwitchInfo
A SwitchStmt, along with a flag indicating if its list of case statements is incomplete (because we d...
SourceLocation FirstCXXOrObjCTryLoc
First C++ 'try' or ObjC @try statement in the current function.
SourceLocation FirstCoroutineStmtLoc
First coroutine statement in the current function.
StringRef getFirstCoroutineStmtKeyword() const
SourceLocation FirstReturnLoc
First 'return' statement in the current function.
enum clang::sema::FunctionScopeInfo::@245 FirstTryType
SourceLocation FirstSEHTryLoc
First SEH '__try' statement in the current function.
void setHasCXXTry(SourceLocation TryLoc)
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound statement scopes in the function.
void setHasSEHTry(SourceLocation TryLoc)
SmallVector< SwitchInfo, 8 > SwitchStack
SwitchStack - This is the current set of active switch statements in the block.
CXXMethodDecl * CallOperator
The lambda's compiler-generated operator().
Provides information about an attempted template argument deduction, whose success or failure was des...
TemplateArgument SecondArg
The second template argument to which the template argument deduction failure refers.
TemplateArgument FirstArg
The first template argument to which the template argument deduction failure refers.
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
bool This(InterpState &S, CodePtr OpPC)
bool Cast(InterpState &S, CodePtr OpPC)
void checkExprLifetimeMustTailArg(Sema &SemaRef, const InitializedEntity &Entity, Expr *Init)
Check that the lifetime of the given expr (and its subobjects) is sufficient, assuming that it is pas...
The JSON file list parser is used to communicate input to InstallAPI.
Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)
@ OR_Deleted
Succeeded, but refers to a deleted function.
@ OR_Success
Overload resolution succeeded.
bool isReservedInAllContexts(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved in all contexts.
IfStatementKind
In an if statement, this denotes whether the statement is a constexpr or consteval if statement.
Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)
Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...
@ RQ_None
No ref-qualifier was provided.
@ OCD_AllCandidates
Requests that all candidates be shown.
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
CapturedRegionKind
The different kinds of captured statement.
@ Result
The result type of a method or function.
ActionResult< Expr * > ExprResult
@ Struct
The "struct" keyword.
bool isLambdaConversionOperator(CXXConversionDecl *C)
ActionResult< Stmt * > StmtResult
@ VK_XValue
An x-value expression is a reference to an object with independent storage but which can be "moved",...
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Expr * IgnoreParensSingleStep(Expr *E)
const FunctionProtoType * T
Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
TemplateDeductionResult
Describes the result of template argument deduction.
@ Success
Template argument deduction was successful.
@ Inconsistent
Template argument deduction produced inconsistent deduced values for the given template parameter.
@ AlreadyDiagnosed
Some error which was already diagnosed.
@ CapturedContext
Parameter for captured context.
Diagnostic wrappers for TextAPI types for error reporting.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
EvalResult is a struct with detailed info about an evaluated expression.
@ MoveEligibleAndCopyElidable
bool isMoveEligible() const
bool isCopyElidable() const
const VarDecl * Candidate
static CatchHandlerType getEmptyKey()
static CatchHandlerType getTombstoneKey()
static unsigned getHashValue(const CatchHandlerType &Base)
static bool isEqual(const CatchHandlerType &LHS, const CatchHandlerType &RHS)