40#include "llvm/ADT/ArrayRef.h"
41#include "llvm/ADT/DenseMap.h"
42#include "llvm/ADT/STLExtras.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);
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);
307 if (
const Decl *FD = CE->getCalleeDecl()) {
310 if (FD->hasAttr<PureAttr>()) {
311 S.
Diag(Loc, diag::warn_unused_call) << R1 << R2 <<
"pure";
314 if (FD->hasAttr<ConstAttr>()) {
315 S.
Diag(Loc, diag::warn_unused_call) << R1 << R2 <<
"const";
319 }
else if (
const auto *CE = dyn_cast<CXXConstructExpr>(E)) {
320 auto [OffendingDecl, A] = CE->getUnusedResultAttr(S.
Context);
324 }
else if (
const auto *ILE = dyn_cast<InitListExpr>(E)) {
325 if (
const TagDecl *TD = ILE->getType()->getAsTagDecl()) {
331 }
else if (ShouldSuppress)
336 if (S.
getLangOpts().ObjCAutoRefCount && ME->isDelegateInitCall()) {
337 S.
Diag(Loc, diag::err_arc_unused_init_message) << R1;
341 auto [OffendingDecl, A] = ME->getUnusedResultAttr(S.
Context);
346 const Expr *Source = POE->getSyntacticForm();
349 POE->getNumSemanticExprs() == 1 &&
351 return DiagnoseUnused(S, POE->getSemanticExpr(0), DiagID);
353 DiagID = diag::warn_unused_container_subscript_expr;
355 DiagID = diag::warn_unused_property_expr;
357 = dyn_cast<CXXFunctionalCastExpr>(E)) {
358 const Expr *E = FC->getSubExpr();
360 E = TE->getSubExpr();
364 if (
const CXXRecordDecl *RD = CE->getType()->getAsCXXRecordDecl())
365 if (!RD->getAttr<WarnUnusedAttr>())
381 S.
Diag(Loc, diag::warn_unused_voidptr)
391 S.
Diag(Loc, diag::warn_unused_volatile) << R1 << R2;
398 if (DiagID == diag::warn_unused_comma_left_operand && S.
isSFINAEContext())
402 S.
PDiag(*DiagID) << R1 << R2);
407 if (
const LabelStmt *Label = dyn_cast_if_present<LabelStmt>(S))
408 S = Label->getSubStmt();
410 const Expr *E = dyn_cast_if_present<Expr>(S);
414 DiagnoseUnused(*
this, E, DiagID);
434 StringRef DeferSpelling =
436 if (DeferSpelling.empty())
437 DeferSpelling =
"_Defer";
438 return DeferSpelling;
446 S.
Diag(DeferLoc, diag::warn_redundant_defer)
459 const unsigned NumElts = Elts.size();
464 const unsigned MixedDeclsCodeID =
getLangOpts().C99
465 ? diag::warn_mixed_decls_code
466 : diag::ext_mixed_decls_code;
494 for (
unsigned i = 0; i != NumElts - 1; ++i)
501 for (
unsigned i = 0; i != NumElts - 1; ++i) {
502 Stmt *Inner = Elts[i + 1]->stripLabelLikeStatements();
545 auto CheckAndFinish = [&](
Expr *E) {
552 llvm::APSInt TempVal;
569 return CheckAndFinish(Val.
get());
583 S.
Diag(KwLoc, diag::err_expansion_stmt_case) << IsDefault;
585 diag::note_enclosing_switch_statement_here);
595 assert((LHSVal.
isInvalid() || LHSVal.
get()) &&
"missing LHS value");
598 "missing RHS value");
601 Diag(CaseLoc, diag::err_case_not_in_switch);
615 Diag(CaseLoc, diag::err_acc_branch_in_out_compute_construct)
621 CaseLoc, DotDotDotLoc, ColonLoc);
634 Diag(DefaultLoc, diag::err_default_not_in_switch);
643 Diag(DefaultLoc, diag::err_acc_branch_in_out_compute_construct)
658 Diag(IdentLoc, diag::err_redefinition_of_label) << TheDecl->
getDeclName();
665 !
Context.getSourceManager().isInSystemHeader(IdentLoc))
666 Diag(IdentLoc, diag::warn_reserved_extern_symbol)
667 << TheDecl << static_cast<int>(Status);
671 if (
getCurScope()->isInOpenACCComputeConstructScope())
702 for (
const auto *A : Attrs) {
703 if (A->getKind() == attr::MustTail) {
718 if (!SemanticAttrs.empty())
728 Expr *E = R->getRetValue();
734 if (!checkMustTailAttr(St, MTA))
740 auto IgnoreImplicitAsWritten = [](
Expr *E) ->
Expr * {
747 R->setRetValue(IgnoreImplicitAsWritten(E));
751bool Sema::checkMustTailAttr(
const Stmt *St,
const Attr &MTA) {
753 "musttail cannot be checked from a dependent context");
756 auto IgnoreParenImplicitAsWritten = [](
const Expr *E) ->
const Expr * {
763 const auto *CE = dyn_cast_or_null<CallExpr>(IgnoreParenImplicitAsWritten(E));
770 if (
const FunctionDecl *CalleeDecl = CE->getDirectCallee();
771 CalleeDecl && CalleeDecl->hasAttr<NotTailCalledAttr>()) {
772 Diag(St->
getBeginLoc(), diag::err_musttail_mismatch) <<
true << CalleeDecl;
773 Diag(CalleeDecl->getLocation(), diag::note_musttail_disabled_by_not_tail_called);
777 if (
const auto *EWC = dyn_cast<ExprWithCleanups>(E)) {
778 if (EWC->cleanupsHaveSideEffects()) {
779 Diag(St->
getBeginLoc(), diag::err_musttail_needs_trivial_args) << &MTA;
790 ft_non_static_member,
791 ft_pointer_to_member,
792 } MemberType = ft_non_member;
795 const FunctionProtoType *
Func;
796 const CXXMethodDecl *
Method =
nullptr;
797 } CallerType, CalleeType;
799 auto GetMethodType = [
this, St, MTA](
const CXXMethodDecl *CMD, FuncType &
Type,
800 bool IsCallee) ->
bool {
803 << IsCallee << isa<CXXDestructorDecl>(CMD);
805 Diag(CMD->getBeginLoc(), diag::note_musttail_structors_forbidden)
811 Type.MemberType = FuncType::ft_static_member;
813 Type.This = CMD->getFunctionObjectParameterType();
814 Type.MemberType = FuncType::ft_non_static_member;
816 Type.Func = CMD->getType()->castAs<FunctionProtoType>();
820 const auto *CallerDecl = dyn_cast<FunctionDecl>(
CurContext);
831 Diag(St->
getBeginLoc(), diag::err_musttail_forbidden_from_this_context)
832 << &MTA << ContextType;
834 }
else if (
const auto *CMD = dyn_cast<CXXMethodDecl>(
CurContext)) {
836 if (!GetMethodType(CMD, CallerType,
false))
840 CallerType.Func = CallerDecl->getType()->getAs<FunctionProtoType>();
843 const Expr *CalleeExpr = CE->getCallee()->IgnoreParens();
844 const auto *CalleeBinOp = dyn_cast<BinaryOperator>(CalleeExpr);
845 SourceLocation CalleeLoc = CE->getCalleeDecl()
846 ? CE->getCalleeDecl()->getBeginLoc()
850 if (
const CXXMethodDecl *CMD =
851 dyn_cast_or_null<CXXMethodDecl>(CE->getCalleeDecl())) {
853 if (!GetMethodType(CMD, CalleeType,
true))
855 }
else if (CalleeBinOp && CalleeBinOp->isPtrMemOp()) {
858 CalleeBinOp->getRHS()->getType()->castAs<MemberPointerType>();
860 Context.getCanonicalTagType(MPT->getMostRecentCXXRecordDecl());
861 CalleeType.Func = MPT->getPointeeType()->castAs<FunctionProtoType>();
862 CalleeType.MemberType = FuncType::ft_pointer_to_member;
875 if (!CalleeType.Func || !CallerType.Func) {
877 if (!CalleeType.Func && CE->getDirectCallee()) {
878 Diag(CE->getDirectCallee()->getBeginLoc(),
879 diag::note_musttail_fix_non_prototype);
881 if (!CallerType.Func)
882 Diag(CallerDecl->getBeginLoc(), diag::note_musttail_fix_non_prototype);
893 if (CallerType.Func->getCallConv() != CalleeType.Func->getCallConv()) {
894 if (
const auto *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl()))
896 <<
true << ND->getDeclName();
898 Diag(St->
getBeginLoc(), diag::err_musttail_callconv_mismatch) <<
false;
899 Diag(CalleeLoc, diag::note_musttail_callconv_mismatch)
906 if (CalleeType.Func->isVariadic() || CallerType.Func->isVariadic()) {
911 const auto *CalleeDecl = CE->getCalleeDecl();
912 if (CalleeDecl && CalleeDecl->hasAttr<CXX11NoReturnAttr>()) {
918 if (CallerType.This.isNull() != CalleeType.This.isNull()) {
919 if (
const auto *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl())) {
921 << CallerType.MemberType << CalleeType.MemberType <<
true
922 << ND->getDeclName();
923 Diag(CalleeLoc, diag::note_musttail_callee_defined_here)
924 << ND->getDeclName();
927 << CallerType.MemberType << CalleeType.MemberType <<
false;
932 auto CheckTypesMatch = [
this](FuncType CallerType, FuncType CalleeType,
933 PartialDiagnostic &PD) ->
bool {
941 auto DoTypesMatch = [
this, &PD](QualType A, QualType B,
942 unsigned Select) ->
bool {
943 if (!
Context.hasSimilarType(A, B)) {
950 if (!CallerType.This.isNull() &&
954 if (!DoTypesMatch(CallerType.Func->getReturnType(),
958 if (CallerType.Func->getNumParams() != CalleeType.Func->getNumParams()) {
960 << CalleeType.Func->getNumParams();
964 ArrayRef<QualType> CalleeParams = CalleeType.Func->getParamTypes();
965 ArrayRef<QualType> CallerParams = CallerType.Func->getParamTypes();
966 size_t N = CallerType.Func->getNumParams();
967 for (
size_t I = 0; I < N; I++) {
968 if (!DoTypesMatch(CalleeParams[I], CallerParams[I],
970 PD << static_cast<int>(I) + 1;
978 PartialDiagnostic PD =
PDiag(diag::note_musttail_mismatch);
979 if (!CheckTypesMatch(CallerType, CalleeType, PD)) {
980 if (
const auto *ND = dyn_cast_or_null<NamedDecl>(CE->getCalleeDecl()))
982 <<
true << ND->getDeclName();
993 for (
auto ArgExpr : CE->arguments()) {
995 Context, ArgExpr->getType(),
false);
1004 typedef EvaluatedExprVisitor<CommaVisitor> Inherited;
1007 CommaVisitor(Sema &SemaRef) : Inherited(SemaRef.Context), SemaRef(SemaRef) {}
1008 void VisitBinaryOperator(BinaryOperator *E) {
1011 EvaluatedExprVisitor<CommaVisitor>::VisitBinaryOperator(E);
1025 bool ConstevalOrNegatedConsteval =
1029 Expr *CondExpr = Cond.
get().second;
1030 assert((CondExpr || ConstevalOrNegatedConsteval) &&
1031 "If statement: missing condition");
1035 CommaVisitor(*this).Visit(CondExpr);
1037 if (!ConstevalOrNegatedConsteval && !elseStmt)
1046 if (ConstevalOrNegatedConsteval ||
1048 auto DiagnoseLikelihood = [&](
const Stmt *S) {
1050 Diags.Report(A->getLocation(),
1051 diag::warn_attribute_has_no_effect_on_compile_time_if)
1052 << A << ConstevalOrNegatedConsteval << A->getRange();
1054 diag::note_attribute_has_no_effect_on_compile_time_if_here)
1055 << ConstevalOrNegatedConsteval
1056 <<
SourceRange(IfLoc, (ConstevalOrNegatedConsteval
1062 DiagnoseLikelihood(thenStmt);
1063 DiagnoseLikelihood(elseStmt);
1065 std::tuple<bool, const Attr *, const Attr *> LHC =
1067 if (std::get<0>(LHC)) {
1068 const Attr *ThenAttr = std::get<1>(LHC);
1069 const Attr *ElseAttr = std::get<2>(LHC);
1071 diag::warn_attributes_likelihood_ifstmt_conflict)
1072 << ThenAttr << ThenAttr->
getRange();
1074 << ElseAttr << ElseAttr->
getRange();
1078 if (ConstevalOrNegatedConsteval) {
1084 if (FD && FD->isImmediateFunction())
1088 Diags.Report(IfLoc, diag::warn_consteval_if_always_true) << Immediate;
1100 return BuildIfStmt(IfLoc, StatementKind, LParenLoc, InitStmt, Cond, RParenLoc,
1101 thenStmt, ElseLoc, elseStmt);
1118 Cond.
get().first, Cond.
get().second, LParenLoc,
1119 RParenLoc, thenStmt, ElseLoc, elseStmt);
1123 struct CaseCompareFunctor {
1124 bool operator()(
const std::pair<llvm::APSInt, CaseStmt*> &LHS,
1125 const llvm::APSInt &RHS) {
1126 return LHS.first < RHS;
1128 bool operator()(
const std::pair<llvm::APSInt, CaseStmt*> &LHS,
1129 const std::pair<llvm::APSInt, CaseStmt*> &RHS) {
1130 return LHS.first < RHS.first;
1132 bool operator()(
const llvm::APSInt &LHS,
1133 const std::pair<llvm::APSInt, CaseStmt*> &RHS) {
1134 return LHS < RHS.first;
1142 const std::pair<llvm::APSInt, CaseStmt*>& rhs) {
1143 if (lhs.first < rhs.first)
1146 if (lhs.first == rhs.first &&
1147 lhs.second->getCaseLoc() < rhs.second->getCaseLoc())
1154static bool CmpEnumVals(
const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,
1155 const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)
1157 return lhs.first < rhs.first;
1162static bool EqEnumVals(
const std::pair<llvm::APSInt, EnumConstantDecl*>& lhs,
1163 const std::pair<llvm::APSInt, EnumConstantDecl*>& rhs)
1165 return lhs.first == rhs.first;
1171 if (
const auto *FE = dyn_cast<FullExpr>(E))
1172 E = FE->getSubExpr();
1173 while (
const auto *ImpCast = dyn_cast<ImplicitCastExpr>(E)) {
1174 if (ImpCast->getCastKind() != CK_IntegralCast)
break;
1175 E = ImpCast->getSubExpr();
1185 SwitchConvertDiagnoser(
Expr *Cond)
1191 return S.
Diag(Loc, diag::err_typecheck_statement_requires_integer) <<
T;
1196 return S.
Diag(Loc, diag::err_switch_incomplete_class_type)
1202 return S.
Diag(Loc, diag::err_switch_explicit_conversion) <<
T << ConvTy;
1213 return S.
Diag(Loc, diag::err_switch_multiple_conversions) <<
T;
1224 llvm_unreachable(
"conversion functions are permitted");
1226 } SwitchDiagnoser(Cond);
1235 Cond = CondResult.
get();
1248 Expr *CondExpr = Cond.
get().second;
1249 assert((Cond.
isInvalid() || CondExpr) &&
"switch with no condition");
1262 Diag(SwitchLoc, diag::warn_bool_switch_condition)
1270 LParenLoc, RParenLoc);
1271 SS->setSwitchLoc(SwitchLoc);
1277static void AdjustAPSInt(llvm::APSInt &Val,
unsigned BitWidth,
bool IsSigned) {
1278 Val = Val.extOrTrunc(BitWidth);
1279 Val.setIsSigned(IsSigned);
1285 unsigned UnpromotedWidth,
bool UnpromotedSign) {
1293 if (UnpromotedWidth < Val.getBitWidth()) {
1294 llvm::APSInt ConvVal(Val);
1295 AdjustAPSInt(ConvVal, UnpromotedWidth, UnpromotedSign);
1296 AdjustAPSInt(ConvVal, Val.getBitWidth(), Val.isSigned());
1301 S.
Diag(Loc, diag::warn_case_value_overflow) <<
toString(Val, 10)
1312 const Expr *CaseExpr,
1313 EnumValsTy::iterator &EI,
1314 EnumValsTy::iterator &EIEnd,
1315 const llvm::APSInt &Val) {
1321 if (
const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
1330 if (ED->
hasAttr<FlagEnumAttr>())
1333 while (EI != EIEnd && EI->first < Val)
1336 if (EI != EIEnd && EI->first == Val)
1347 const EnumType *CondEnumType = CondType->
getAsCanonical<EnumType>();
1348 const EnumType *CaseEnumType = CaseType->
getAsCanonical<EnumType>();
1349 if (!CondEnumType || !CaseEnumType)
1353 if (!CondEnumType->getDecl()->getIdentifier() &&
1354 !CondEnumType->getDecl()->getTypedefNameForAnonDecl())
1356 if (!CaseEnumType->getDecl()->getIdentifier() &&
1357 !CaseEnumType->getDecl()->getTypedefNameForAnonDecl())
1363 S.
Diag(Case->
getExprLoc(), diag::warn_comparison_of_mixed_enum_types_switch)
1373 assert(SS ==
getCurFunction()->SwitchStack.back().getPointer() &&
1374 "switch stack missing push/pop!");
1403 const Expr *CondExprBeforePromotion = CondExpr;
1409 bool HasDependentValue
1411 unsigned CondWidth = HasDependentValue ? 0 :
Context.getIntWidth(CondType);
1418 unsigned CondWidthBeforePromotion
1419 = HasDependentValue ? 0 :
Context.getIntWidth(CondTypeBeforePromotion);
1420 bool CondIsSignedBeforePromotion
1427 CaseValsTy CaseVals;
1430 typedef std::vector<std::pair<llvm::APSInt, CaseStmt*> > CaseRangesTy;
1431 CaseRangesTy CaseRanges;
1435 bool CaseListIsErroneous =
false;
1441 SC = SC->getNextSwitchCase()) {
1443 if (
DefaultStmt *DS = dyn_cast<DefaultStmt>(SC)) {
1444 if (TheDefaultStmt) {
1445 Diag(DS->getDefaultLoc(), diag::err_multiple_default_labels_defined);
1452 CaseListIsErroneous =
true;
1454 TheDefaultStmt = DS;
1462 HasDependentValue =
true;
1468 const Expr *LoBeforePromotion = Lo;
1475 CondIsSignedBeforePromotion);
1487 HasDependentValue =
true;
1490 CaseRanges.push_back(std::make_pair(LoVal, CS));
1492 CaseVals.push_back(std::make_pair(LoVal, CS));
1496 if (!HasDependentValue) {
1499 llvm::APSInt ConstantCondValue;
1500 bool HasConstantCond =
false;
1501 if (!TheDefaultStmt) {
1506 ConstantCondValue =
Result.Val.getInt();
1507 assert(!HasConstantCond ||
1508 (ConstantCondValue.getBitWidth() == CondWidth &&
1509 ConstantCondValue.isSigned() == CondIsSigned));
1510 Diag(SwitchLoc, diag::warn_switch_default);
1512 bool ShouldCheckConstantCond = HasConstantCond;
1517 if (!CaseVals.empty()) {
1518 for (
unsigned i = 0, e = CaseVals.size(); i != e; ++i) {
1519 if (ShouldCheckConstantCond &&
1520 CaseVals[i].first == ConstantCondValue)
1521 ShouldCheckConstantCond =
false;
1523 if (i != 0 && CaseVals[i].first == CaseVals[i-1].first) {
1526 StringRef PrevString, CurrString;
1529 if (
DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(PrevCase)) {
1530 PrevString = DeclRef->getDecl()->getName();
1532 if (
DeclRefExpr *DeclRef = dyn_cast<DeclRefExpr>(CurrCase)) {
1533 CurrString = DeclRef->getDecl()->getName();
1536 CaseVals[i-1].first.toString(CaseValStr);
1538 if (PrevString == CurrString)
1539 Diag(CaseVals[i].second->getLHS()->getBeginLoc(),
1540 diag::err_duplicate_case)
1541 << (PrevString.empty() ? CaseValStr.str() : PrevString);
1543 Diag(CaseVals[i].second->getLHS()->getBeginLoc(),
1544 diag::err_duplicate_case_differing_expr)
1545 << (PrevString.empty() ? CaseValStr.str() : PrevString)
1546 << (CurrString.empty() ? CaseValStr.str() : CurrString)
1549 Diag(CaseVals[i - 1].second->getLHS()->getBeginLoc(),
1550 diag::note_duplicate_case_prev);
1553 CaseListIsErroneous =
true;
1560 if (!CaseRanges.empty()) {
1563 llvm::stable_sort(CaseRanges);
1566 std::vector<llvm::APSInt> HiVals;
1567 for (
unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {
1568 llvm::APSInt &LoVal = CaseRanges[i].first;
1569 CaseStmt *CR = CaseRanges[i].second;
1572 const Expr *HiBeforePromotion = Hi;
1579 CondWidthBeforePromotion, CondIsSignedBeforePromotion);
1585 if (LoVal > HiVal) {
1588 CaseRanges.erase(CaseRanges.begin()+i);
1594 if (ShouldCheckConstantCond &&
1595 LoVal <= ConstantCondValue &&
1596 ConstantCondValue <= HiVal)
1597 ShouldCheckConstantCond =
false;
1599 HiVals.push_back(HiVal);
1605 for (
unsigned i = 0, e = CaseRanges.size(); i != e; ++i) {
1606 llvm::APSInt &CRLo = CaseRanges[i].first;
1607 llvm::APSInt &CRHi = HiVals[i];
1608 CaseStmt *CR = CaseRanges[i].second;
1613 llvm::APSInt OverlapVal(32);
1617 CaseValsTy::iterator I =
1618 llvm::lower_bound(CaseVals, CRLo, CaseCompareFunctor());
1619 if (I != CaseVals.end() && I->first < CRHi) {
1620 OverlapVal = I->first;
1621 OverlapStmt = I->second;
1625 I = std::upper_bound(I, CaseVals.end(), CRHi, CaseCompareFunctor());
1626 if (I != CaseVals.begin() && (I-1)->first >= CRLo) {
1627 OverlapVal = (I-1)->first;
1628 OverlapStmt = (I-1)->second;
1633 if (i && CRLo <= HiVals[i-1]) {
1634 OverlapVal = HiVals[i-1];
1635 OverlapStmt = CaseRanges[i-1].second;
1643 diag::note_duplicate_case_prev);
1646 CaseListIsErroneous =
true;
1652 if (!CaseListIsErroneous && !CaseListIsIncomplete &&
1653 ShouldCheckConstantCond) {
1656 Diag(CondExpr->
getExprLoc(), diag::warn_missing_case_for_condition)
1667 if (!CaseListIsErroneous && !CaseListIsIncomplete && !HasConstantCond &&
1670 if (!ED->isCompleteDefinition() || ED->enumerators().empty())
1677 for (
auto *EDI : ED->enumerators()) {
1678 llvm::APSInt Val = EDI->getInitVal();
1680 EnumVals.push_back(std::make_pair(Val, EDI));
1683 auto EI = EnumVals.begin(), EIEnd = llvm::unique(EnumVals,
EqEnumVals);
1686 for (CaseValsTy::const_iterator CI = CaseVals.begin();
1687 CI != CaseVals.end(); CI++) {
1688 Expr *CaseExpr = CI->second->getLHS();
1692 << CondTypeBeforePromotion;
1696 EI = EnumVals.begin();
1697 for (CaseRangesTy::const_iterator RI = CaseRanges.begin();
1698 RI != CaseRanges.end(); RI++) {
1699 Expr *CaseExpr = RI->second->getLHS();
1703 << CondTypeBeforePromotion;
1706 RI->second->getRHS()->EvaluateKnownConstInt(
Context);
1709 CaseExpr = RI->second->getRHS();
1713 << CondTypeBeforePromotion;
1717 auto CI = CaseVals.begin();
1718 auto RI = CaseRanges.begin();
1719 bool hasCasesNotInSwitch =
false;
1723 for (EI = EnumVals.begin(); EI != EIEnd; EI++) {
1725 switch (EI->second->getAvailability()) {
1742 if (EI->second->hasAttr<UnusedAttr>())
1746 while (CI != CaseVals.end() && CI->first < EI->first)
1749 if (CI != CaseVals.end() && CI->first == EI->first)
1753 for (; RI != CaseRanges.end(); RI++) {
1755 RI->second->getRHS()->EvaluateKnownConstInt(
Context);
1757 if (EI->first <= Hi)
1761 if (RI == CaseRanges.end() || EI->first < RI->first) {
1762 hasCasesNotInSwitch =
true;
1763 UnhandledNames.push_back(EI->second->getDeclName());
1767 if (TheDefaultStmt && UnhandledNames.empty() && ED->isClosedNonFlag())
1771 if (!UnhandledNames.empty()) {
1773 ? diag::warn_def_missing_case
1774 : diag::warn_missing_case)
1777 for (
size_t I = 0, E = std::min(UnhandledNames.size(), (
size_t)3);
1779 DB << UnhandledNames[I];
1782 if (!hasCasesNotInSwitch)
1790 diag::warn_empty_switch_body);
1794 if (CaseListIsErroneous)
1808 Context.hasSameUnqualifiedType(SrcType, DstType))
1815 if (!ED->isClosed())
1818 if (
Diags.isIgnored(diag::warn_not_in_enum_assignment, SrcExpr->
getExprLoc()))
1826 unsigned DstWidth =
Context.getIntWidth(DstType);
1830 if (ED->hasAttr<FlagEnumAttr>()) {
1839 auto &Values = It->second;
1842 Values.reserve(std::distance(ED->enumerator_begin(), ED->enumerator_end()));
1844 for (
auto *EC : ED->enumerators()) {
1845 Values.push_back(EC->getInitVal());
1853 Values.erase(llvm::unique(Values), Values.end());
1856 if (llvm::binary_search(Values, *RHSVal))
1868 CommaVisitor(S).Visit(CondExpr);
1903 auto CondVal = Cond.
get();
1908 WhileLoc, LParenLoc, RParenLoc);
1915 assert(Cond &&
"ActOnDoStmt(): missing expression");
1920 Cond = CondResult.
get();
1925 Cond = CondResult.
get();
1936 return new (
Context)
DoStmt(Body, Cond, DoLoc, WhileLoc, CondRParen);
1947 DeclSetVector &Decls;
1953 DeclExtractor(
Sema &S, DeclSetVector &Decls,
1955 Inherited(S.Context),
1960 bool isSimple() {
return Simple; }
1963 void VisitMemberExpr(MemberExpr* E) {
1969 void VisitStmt(Stmt *S) { Simple =
false; }
1971 void VisitBinaryOperator(BinaryOperator *E) {
1980 void VisitUnaryOperator(UnaryOperator *E) {
1988 void VisitConditionalOperator(ConditionalOperator *E) {
1994 void VisitParenExpr(ParenExpr *E) {
1998 void VisitBinaryConditionalOperator(BinaryConditionalOperator *E) {
2003 void VisitIntegerLiteral(IntegerLiteral *E) { }
2004 void VisitFloatingLiteral(FloatingLiteral *E) { }
2005 void VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *E) { }
2006 void VisitCharacterLiteral(CharacterLiteral *E) { }
2007 void VisitGNUNullExpr(GNUNullExpr *E) { }
2008 void VisitImaginaryLiteral(ImaginaryLiteral *E) { }
2010 void VisitDeclRefExpr(DeclRefExpr *E) {
2011 VarDecl *VD = dyn_cast<VarDecl>(E->
getDecl());
2028 DeclSetVector &Decls;
2032 typedef EvaluatedExprVisitor<DeclMatcher> Inherited;
2034 DeclMatcher(Sema &S, DeclSetVector &Decls, Stmt *Statement) :
2035 Inherited(S.Context), Decls(Decls), FoundDecl(
false) {
2036 if (!Statement)
return;
2041 void VisitReturnStmt(ReturnStmt *S) {
2045 void VisitBreakStmt(BreakStmt *S) {
2049 void VisitGotoStmt(GotoStmt *S) {
2060 void CheckLValueToRValueCast(Expr *E) {
2067 if (ConditionalOperator *CO = dyn_cast<ConditionalOperator>(E)) {
2068 Visit(CO->getCond());
2069 CheckLValueToRValueCast(CO->getTrueExpr());
2070 CheckLValueToRValueCast(CO->getFalseExpr());
2074 if (BinaryConditionalOperator *BCO =
2075 dyn_cast<BinaryConditionalOperator>(E)) {
2076 CheckLValueToRValueCast(BCO->getOpaqueValue()->getSourceExpr());
2077 CheckLValueToRValueCast(BCO->getFalseExpr());
2084 void VisitDeclRefExpr(DeclRefExpr *E) {
2085 if (
const auto *VD = dyn_cast<VarDecl>(E->
getDecl())) {
2086 if (Decls.count(VD))
2088 }
else if (
const auto *MD = dyn_cast<CXXMethodDecl>(E->
getDecl());
2099 for (
const auto &
Capture : MD->getParent()->captures()) {
2100 if (!
Capture.capturesVariable())
2107 const auto *VD = dyn_cast<VarDecl>(
Capture.getCapturedVar());
2108 if (VD && Decls.count(VD))
2114 void VisitPseudoObjectExpr(PseudoObjectExpr *POE) {
2118 if (
auto *OVE = dyn_cast<OpaqueValueExpr>(S))
2120 Visit(OVE->getSourceExpr());
2126 bool FoundDeclInUse() {
return FoundDecl; }
2130 void CheckForLoopConditionalStatement(
Sema &S,
Expr *Second,
2133 if (!Second)
return;
2140 DeclSetVector Decls;
2142 DeclExtractor DE(S, Decls, Ranges);
2146 if (!DE.isSimple())
return;
2149 if (Decls.size() == 0)
return;
2152 for (
auto *VD : Decls)
2156 if (DeclMatcher(S, Decls, Second).FoundDeclInUse() ||
2157 DeclMatcher(S, Decls, Third).FoundDeclInUse() ||
2158 DeclMatcher(S, Decls, Body).FoundDeclInUse())
2162 if (Decls.size() > 4) {
2165 PDiag << (unsigned)Decls.size();
2166 for (
auto *VD : Decls)
2170 for (
auto Range : Ranges)
2173 S.
Diag(Ranges.begin()->getBegin(), PDiag);
2178 bool ProcessIterationStmt(
Sema &S,
Stmt* Statement,
bool &Increment,
2180 if (
auto Cleanups = dyn_cast<ExprWithCleanups>(Statement))
2181 if (!Cleanups->cleanupsHaveSideEffects())
2184 if (
UnaryOperator *UO = dyn_cast<UnaryOperator>(Statement)) {
2185 switch (UO->getOpcode()) {
2186 default:
return false;
2196 DRE = dyn_cast<DeclRefExpr>(UO->getSubExpr());
2204 default:
return false;
2212 DRE = dyn_cast<DeclRefExpr>(
Call->getArg(0));
2222 SourceLocation BreakLoc;
2223 SourceLocation ContinueLoc;
2224 bool InSwitch =
false;
2227 BreakContinueFinder(Sema &S,
const Stmt* Body) :
2228 Inherited(S.Context) {
2232 typedef ConstEvaluatedExprVisitor<BreakContinueFinder> Inherited;
2234 void VisitContinueStmt(
const ContinueStmt* E) {
2238 void VisitBreakStmt(
const BreakStmt* E) {
2243 void VisitSwitchStmt(
const SwitchStmt* S) {
2248 if (
const Stmt *Cond = S->
getCond())
2253 if (
const Stmt *Body = S->
getBody())
2258 void VisitForStmt(
const ForStmt *S) {
2265 void VisitWhileStmt(
const WhileStmt *) {
2270 void VisitDoStmt(
const DoStmt *) {
2275 void VisitCXXForRangeStmt(
const CXXForRangeStmt *S) {
2288 void VisitObjCForCollectionStmt(
const ObjCForCollectionStmt *S) {
2297 bool ContinueFound() {
return ContinueLoc.
isValid(); }
2298 bool BreakFound() {
return BreakLoc.
isValid(); }
2299 SourceLocation GetContinueLoc() {
return ContinueLoc; }
2300 SourceLocation GetBreakLoc() {
return BreakLoc; }
2309 void CheckForRedundantIteration(
Sema &S,
Expr *Third,
Stmt *Body) {
2311 if (!Body || !Third)
return;
2317 if (!LastStmt)
return;
2323 bool LoopIncrement, LastIncrement;
2326 if (!ProcessIterationStmt(S, Third, LoopIncrement, LoopDRE))
return;
2327 if (!ProcessIterationStmt(S, LastStmt, LastIncrement, LastDRE))
return;
2331 if (LoopIncrement != LastIncrement ||
2334 if (BreakContinueFinder(S, Body).ContinueFound())
return;
2337 << LastDRE->
getDecl() << LastIncrement;
2356 const Decl *NonVarSeen =
nullptr;
2357 bool VarDeclSeen =
false;
2358 for (
auto *DI : DS->decls()) {
2359 if (
VarDecl *VD = dyn_cast<VarDecl>(DI)) {
2363 diag_compat::non_local_variable_decl_in_for);
2364 }
else if (!NonVarSeen) {
2378 if (NonVarSeen && !VarDeclSeen)
2380 diag_compat::non_variable_decl_in_for);
2384 if (!Second.
get().first)
2385 CheckForLoopConditionalStatement(*
this, Second.
get().second, third.
get(),
2387 CheckForRedundantIteration(*
this, third.
get(), Body);
2395 Body, ForLoc, LParenLoc, RParenLoc);
2415 if (
Decl->getType()->isUndeducedType()) {
2428 SemaRef.
Diag(Loc, DiagID) <<
Init->getType();
2432 Decl->getTypeSourceInfo()->getTypeLoc(),
Init, InitType, Info);
2435 SemaRef.
Diag(Loc, DiagID) <<
Init->getType();
2442 Decl->setType(InitType);
2460enum BeginEndFunction {
2469void NoteForRangeBeginEndFunction(
Sema &SemaRef,
Expr *E,
2470 BeginEndFunction BEF) {
2471 CallExpr *CE = dyn_cast<CallExpr>(E);
2479 std::string Description;
2480 bool IsTemplate =
false;
2487 SemaRef.
Diag(Loc, diag::note_for_range_begin_end)
2488 << BEF << IsTemplate << Description << E->
getType();
2505 Decl->setCXXForRangeImplicitVar(
true);
2508 Decl->setConstexpr(
true);
2521 const auto DepthStr = std::to_string(S->
getDepth() / 2);
2523 PP.getIdentifierInfo(std::string(
"__range") + DepthStr);
2527 diag::err_for_range_deduction_failure))
2549 return Diag(InitStmt->
getBeginLoc(), diag::err_objc_for_range_init_stmt)
2555 assert(DS &&
"first part of for range not a decl stmt");
2583 if (RangeDecl.isInvalid()) {
2589 ForLoc, CoawaitLoc, InitStmt, ColonLoc, RangeDecl.get(),
2591 nullptr,
nullptr, DS, RParenLoc, Kind,
2592 LifetimeExtendTemps);
2593 if (R.isInvalid()) {
2615 ExprResult *EndExpr, BeginEndFunction *BEF) {
2625 auto BuildBegin = [&] {
2629 BeginMemberLookup, CandidateSet,
2630 BeginRange, BeginExpr);
2635 << ColonLoc << BEF_begin << BeginRange->
getType();
2648 diag::err_for_range_iter_deduction_failure)) {
2649 NoteForRangeBeginEndFunction(SemaRef, BeginExpr->
get(), *BEF);
2655 auto BuildEnd = [&] {
2659 EndMemberLookup, CandidateSet,
2664 << ColonLoc << BEF_end << EndRange->
getType();
2668 diag::err_for_range_iter_deduction_failure)) {
2669 NoteForRangeBeginEndFunction(SemaRef, EndExpr->
get(), *BEF);
2689 if (BeginMemberLookup.
empty() != EndMemberLookup.
empty()) {
2694 auto BuildNonmember = [&](
2704 switch (BuildFound()) {
2711 SemaRef.
PDiag(diag::err_for_range_invalid)
2712 << BeginRange->
getType() << BEFFound),
2719 diag::note_for_range_member_begin_end_ignored)
2720 << BeginRange->
getType() << BEFFound;
2724 llvm_unreachable(
"unexpected ForRangeStatus");
2726 if (BeginMemberLookup.
empty())
2727 return BuildNonmember(BEF_end, EndMemberLookup, BuildEnd, BuildBegin);
2728 return BuildNonmember(BEF_begin, BeginMemberLookup, BuildBegin, BuildEnd);
2760 AdjustedRange = SemaRef.
BuildUnaryOp(S, RangeLoc, UO_Deref, Range);
2765 S, ForLoc, CoawaitLoc, InitStmt, LoopVarDecl, ColonLoc,
2774 SemaRef.
Diag(RangeLoc, diag::err_for_range_dereference)
2777 S, ForLoc, CoawaitLoc, InitStmt, LoopVarDecl, ColonLoc,
2783 if (Temporaries.empty())
2787 for (
auto *MTE : Temporaries)
2796 llvm::function_ref<
StmtResult()> RebuildWithDereference,
2816 QualType RangeType = Range->getType();
2819 diag::err_for_range_incomplete_type))
2824 const auto DepthStr = std::to_string(S->
getDepth() / 2);
2826 BeginName =
PP.getIdentifierInfo(std::string(
"__begin") + DepthStr);
2828 EndName =
PP.getIdentifierInfo(std::string(
"__end") + DepthStr);
2843 BeginExpr = BeginRangeRef;
2850 diag::err_for_range_iter_deduction_failure)) {
2851 NoteForRangeBeginEndFunction(*
this, BeginExpr.
get(), BEF_begin);
2859 Context, CAT->getSize(),
Context.getPointerDiffType(), RangeLoc);
2861 dyn_cast<VariableArrayType>(UnqAT)) {
2888 VAT->desugar(), RangeLoc))
2898 VAT->getElementType(), RangeLoc))
2906 SizeOfEachElementExprR.
get());
2913 llvm_unreachable(
"Unexpected array type in for-range");
2922 diag::err_for_range_iter_deduction_failure)) {
2923 NoteForRangeBeginEndFunction(*
this, EndExpr.
get(), BEF_end);
2929 BeginEndFunction BEFFailure;
2932 RangeType, BeginVar, EndVar, ColonLoc, CoawaitLoc,
2933 &CandidateSet, &BeginExpr, &EndExpr, &BEFFailure);
2936 BEFFailure == BEF_begin) {
2939 if (
DeclRefExpr *DRE = dyn_cast<DeclRefExpr>(Range)) {
2941 QualType ArrayTy = PVD->getOriginalType();
2942 QualType PointerTy = PVD->getType();
2944 Diag(Range->getBeginLoc(), diag::err_range_on_array_parameter)
2945 << RangeLoc << PVD << ArrayTy << PointerTy;
2946 Diag(PVD->getLocation(), diag::note_declared_at);
2954 if (RebuildWithDereference) {
2955 assert(RebuildResult);
2958 *RebuildResult = SR;
2966 Expr *Range = BEFFailure ? EndRangeRef.
get() : BeginRangeRef.
get();
2969 PDiag(diag::err_for_range_invalid)
2970 << RangeLoc << Range->getType()
2980 "invalid range expression in for loop");
2982 return {BeginVar, EndVar, BeginExpr.
get(), EndExpr.
get()};
2990 if (
auto *DD = dyn_cast<DecompositionDecl>(LoopVar))
2991 for (
auto *Binding : DD->bindings()) {
2992 if (!Binding->isParameterPack())
2993 Binding->setType(
Context.DependentTy);
3031 }
else if (!BeginDeclStmt.
get()) {
3033 auto RebuildWithDereference = [&] {
3035 *
this, S, ForLoc, CoawaitLoc, InitStmt, LoopVarDecl, ColonLoc,
3040 S, RangeVar, ColonLoc, CoawaitLoc, LifetimeExtendTemps, Kind,
3041 false, &RebuildResult, RebuildWithDereference);
3044 return RebuildResult;
3050 auto [BeginVar, EndVar, BeginExpr, EndExpr] = ForRangeInfo;
3052 QualType BeginType = BeginVar->getType(), EndType = EndVar->getType();
3053 if (!
Context.hasSameType(BeginType, EndType)) {
3054 DiagCompat(RangeLoc, diag_compat::for_range_begin_end_types_differ)
3055 << BeginType << EndType;
3056 NoteForRangeBeginEndFunction(*
this, BeginExpr, BEF_begin);
3057 NoteForRangeBeginEndFunction(*
this, EndExpr, BEF_end);
3077 NotEqExpr =
ActOnBinOp(S, ColonLoc, tok::exclaimequal,
3078 BeginRef.
get(), EndRef.
get());
3085 Diag(RangeLoc, diag::note_for_range_invalid_iterator)
3086 << RangeLoc << diag::InvalidRangeForIterator::OpNotEq
3088 NoteForRangeBeginEndFunction(*
this, BeginExpr, BEF_begin);
3089 if (!
Context.hasSameType(BeginType, EndType))
3090 NoteForRangeBeginEndFunction(*
this, EndExpr, BEF_end);
3101 if (!IncrExpr.isInvalid() && CoawaitLoc.
isValid())
3106 if (!IncrExpr.isInvalid())
3108 if (IncrExpr.isInvalid()) {
3109 Diag(RangeLoc, diag::note_for_range_invalid_iterator)
3110 << RangeLoc << diag::InvalidRangeForIterator::OpAdvance
3112 NoteForRangeBeginEndFunction(*
this, BeginExpr, BEF_begin);
3124 Diag(RangeLoc, diag::note_for_range_invalid_iterator)
3125 << RangeLoc << diag::InvalidRangeForIterator::OpDeref
3127 NoteForRangeBeginEndFunction(*
this, BeginExpr, BEF_begin);
3137 NoteForRangeBeginEndFunction(*
this, BeginExpr, BEF_begin);
3154 LifetimeExtendTemps);
3157 InitStmt, RangeDS, cast_or_null<DeclStmt>(BeginDeclStmt.
get()),
3158 cast_or_null<DeclStmt>(EndDeclStmt.
get()), NotEqExpr.
get(),
3159 IncrExpr.get(), LoopVarDS,
nullptr, ForLoc, CoawaitLoc,
3160 ColonLoc, RParenLoc);
3179 if (
auto Cleanups = dyn_cast<ExprWithCleanups>(InitExpr))
3180 if (!Cleanups->cleanupsHaveSideEffects())
3181 InitExpr = Cleanups->getSubExpr();
3184 dyn_cast<MaterializeTemporaryExpr>(InitExpr);
3215 ReferenceReturnType = ReturnType;
3218 if (!ReferenceReturnType.
isNull()) {
3223 diag::warn_for_range_const_ref_binds_temp_built_from_ref)
3224 << VD << VariableType << ReferenceReturnType;
3237 SemaRef.
Diag(VD->
getLocation(), diag::warn_for_range_ref_binds_ret_temp)
3238 << VD << RangeInitType;
3251 return RD->hasAttr<TrivialABIAttr>();
3268 if (!CE->getConstructor()->isCopyConstructor())
3270 }
else if (
const CastExpr *CE = dyn_cast<CastExpr>(InitExpr)) {
3271 if (CE->getCastKind() != CK_LValueToRValue)
3289 << VD << VariableType;
3311 diag::warn_for_range_const_ref_binds_temp_built_from_ref, Loc) &&
3312 SemaRef.
Diags.
isIgnored(diag::warn_for_range_ref_binds_ret_temp, Loc) &&
3335 ForStmt->getRangeInit()->getType());
3352 diag::warn_empty_range_based_for_body);
3366 if (
getCurScope()->isInOpenACCComputeConstructScope())
3400 if (
getCurScope()->isInOpenACCComputeConstructScope())
3407 const Scope &DestScope,
3408 unsigned DeferJumpKind) {
3411 S.
Diag(Loc, diag::warn_jump_out_of_seh_finally);
3420 if (DestScope.
Contains(*Parent) || &DestScope == Parent)
3421 S.
Diag(Loc, diag::err_jump_out_of_defer_stmt) << DeferJumpKind;
3430 assert(
Target &&
"not a named break/continue?");
3440 S.
Diag(KWLoc, diag::err_acc_branch_in_out_compute_construct)
3453 if (IsContinue && !
Found->isContinueScope()) {
3454 S.
Diag(LabelLoc, diag::err_continue_switch);
3460 S.
Diag(LabelLoc, diag::err_break_continue_label_not_found) << IsContinue;
3479 return StmtError(
Diag(ContinueLoc, diag::err_continue_not_in_loop));
3487 Diag(ContinueLoc, diag::err_acc_branch_in_out_compute_construct)
3491 diag::DeferJumpKind::Continue);
3511 return StmtError(
Diag(BreakLoc, diag::err_break_not_in_loop_or_switch));
3515 return StmtError(
Diag(BreakLoc, diag::err_omp_loop_cannot_use_stmt)
3529 Diag(BreakLoc, diag::err_acc_branch_in_out_compute_construct)
3533 diag::DeferJumpKind::Break);
3544 const auto *DR = dyn_cast<DeclRefExpr>(E->
IgnoreParens());
3545 if (!DR || DR->refersToEnclosingVariableOrCapture())
3547 const auto *VD = dyn_cast<VarDecl>(DR->getDecl());
3570 if (VD->
getKind() == Decl::ParmVar)
3572 else if (VD->
getKind() != Decl::Var)
3585 if (VD->
hasAttr<BlocksAttr>())
3621 auto invalidNRVO = [&] {
3630 if ((ReturnType->
getTypeClass() == Type::TypeClass::Auto &&
3633 return invalidNRVO();
3639 return invalidNRVO();
3645 !
Context.hasSameUnqualifiedType(ReturnType, VDType))
3659 const auto *Step = llvm::find_if(
Seq.steps(), [](
const auto &Step) {
3660 return Step.Kind == InitializationSequence::SK_ConstructorInitialization ||
3661 Step.Kind == InitializationSequence::SK_UserConversion;
3663 if (Step !=
Seq.step_end()) {
3664 const auto *FD = Step->Function.Function;
3675 bool SupressSimplerImplicitMoves) {
3681 Expr *InitExpr = &AsRvalue;
3683 Value->getBeginLoc());
3685 auto Res =
Seq.getFailedOverloadResult();
3696 return Seq.Perform(*
this, Entity, Kind,
Value);
3716 bool SupressSimplerImplicitMoves) {
3724 bool HasDeducedReturnType =
3734 RetValExp = ER.
get();
3740 if (HasDeducedReturnType) {
3753 assert(AT &&
"lost auto type from lambda return type");
3769 RetValExp =
Result.get();
3784 Diag(ReturnLoc, diag::err_lambda_return_init_list)
3786 RetValExp =
nullptr;
3799 if (
auto *CurBlock = dyn_cast<BlockScopeInfo>(CurCap)) {
3801 Diag(ReturnLoc, diag::err_noreturn_has_return_expr)
3802 << diag::FalloffFunctionKind::Block;
3805 }
else if (
auto *CurRegion = dyn_cast<CapturedRegionScopeInfo>(CurCap)) {
3806 Diag(ReturnLoc, diag::err_return_in_captured_stmt) << CurRegion->getRegionName();
3809 assert(CurLambda &&
"unknown kind of captured scope");
3813 Diag(ReturnLoc, diag::err_noreturn_has_return_expr)
3814 << diag::FalloffFunctionKind::Lambda;
3826 if (isa_and_nonnull<InitListExpr>(RetValExp)) {
3827 Diag(ReturnLoc, diag::err_return_block_has_expr)
3828 << (CurLambda !=
nullptr);
3829 RetValExp =
nullptr;
3834 Diag(ReturnLoc, diag::ext_return_has_void_expr) <<
"literal" << 2;
3836 Diag(ReturnLoc, diag::err_return_block_has_expr)
3837 << (CurLambda !=
nullptr);
3838 RetValExp =
nullptr;
3841 }
else if (!RetValExp) {
3842 return StmtError(
Diag(ReturnLoc, diag::err_block_return_missing_expr));
3855 Entity, NRInfo, RetValExp, SupressSimplerImplicitMoves);
3860 RetValExp = Res.
get();
3861 CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc);
3869 RetValExp = ER.
get();
3883 if (
auto *CurBlock = dyn_cast<BlockScopeInfo>(CurCap);
3886 CurBlock->TheDecl->setInvalidDecl();
3906 LocalTypedefNameReferencer(
Sema &S) : S(S) {}
3907 bool VisitRecordType(RecordType *RT)
override;
3912bool LocalTypedefNameReferencer::VisitRecordType(RecordType *RT) {
3913 auto *
R = dyn_cast<CXXRecordDecl>(RT->getDecl());
3914 if (!R || !
R->isLocalClass() || !
R->isLocalClass()->isExternallyVisible() ||
3915 R->isDependentType())
3917 for (
auto *TmpD :
R->decls())
3918 if (
auto *
T = dyn_cast<TypedefNameDecl>(TmpD))
3920 S.MarkAnyDeclReferenced(
T->getLocation(),
T,
false);
3934 Expr *RetExpr,
const AutoType *AT) {
3941 if (isa_and_nonnull<InitListExpr>(RetExpr)) {
3946 : diag::err_auto_fn_return_init_list)
3956 assert(AT->isDeduced() &&
"should have deduced to dependent type");
3970 Diag(ReturnLoc, diag::err_auto_fn_return_void_but_not_auto)
3986 if (FindResult.Expression)
3987 TemplateSpecLoc = FindResult.Expression->getNameLoc();
3991 OrigResultType, RetExpr,
Deduced, Info,
false,
4007 Diag(ReturnLoc, diag::err_typecheck_missing_return_type_incompatible)
4010 Diag(ReturnLoc, diag::err_auto_fn_different_deductions)
4011 << (AT->isDecltypeAuto() ? 1 : 0) << Info.
SecondArg
4025 LocalTypedefNameReferencer(*this).TraverseType(RetExpr->
getType());
4042 diag::warn_qual_return_type,
4054 if (
getCurScope()->isInOpenACCComputeConstructScope())
4056 Diag(ReturnLoc, diag::err_acc_branch_in_out_compute_construct)
4063 "first coroutine location not set");
4064 Diag(ReturnLoc, diag::err_return_in_coroutine);
4069 CheckInvalidBuiltinCountedByRef(RetVal.
get(),
4074 if (R.isInvalid() ||
ExprEvalContexts.back().isDiscardedStatementContext())
4080 CurScope->updateNRVOCandidate(VD);
4083 diag::DeferJumpKind::Return);
4098 [[maybe_unused]]
Scope *CurScope) {
4115 if (DC->isStdNamespace())
4122 bool AllowRecovery) {
4130 bool SupressSimplerImplicitMoves =
4138 SupressSimplerImplicitMoves);
4142 const AttrVec *Attrs =
nullptr;
4143 bool isObjCMethod =
false;
4151 Diag(ReturnLoc, diag::warn_noreturn_function_has_return_expr) << FD;
4152 if (FD->
isMain() && RetValExp)
4154 Diag(ReturnLoc, diag::warn_main_returns_bool_literal)
4156 if (FD->
hasAttr<CmseNSEntryAttr>() && RetValExp) {
4158 if (RT->getDecl()->isOrContainsUnion())
4163 FnRetType = MD->getReturnType();
4164 isObjCMethod =
true;
4166 Attrs = &MD->getAttrs();
4167 if (MD->hasRelatedResultType() && MD->getClassInterface()) {
4171 RelatedRetType =
Context.getObjCInterfaceType(MD->getClassInterface());
4172 RelatedRetType =
Context.getObjCObjectPointerType(RelatedRetType);
4178 const auto *ATy = dyn_cast<ArrayType>(RetValExp->
getType());
4179 if (ATy && ATy->getElementType().isWebAssemblyReferenceType()) {
4180 Diag(ReturnLoc, diag::err_wasm_table_art) << 1;
4194 RetValExp = ER.
get();
4220 AT->isDeduced() ? FnRetType :
QualType());
4221 if (Recovery.isInvalid())
4223 RetValExp = Recovery.get();
4239 if (
auto *ILE = dyn_cast<InitListExpr>(RetValExp)) {
4244 int FunctionKind = 0;
4252 Diag(ReturnLoc, diag::err_return_init_list)
4256 RetValExp = AllowRecovery
4258 ILE->getRBraceLoc(), ILE->inits())
4263 unsigned D = diag::ext_return_has_expr;
4268 D = diag::err_ctor_dtor_returns_void;
4270 D = diag::ext_return_has_void_expr;
4277 RetValExp =
Result.get();
4282 if (D == diag::err_ctor_dtor_returns_void) {
4284 Diag(ReturnLoc, D) << CurDecl << isa<CXXDestructorDecl>(CurDecl)
4288 else if (D != diag::ext_return_has_void_expr ||
4292 int FunctionKind = 0;
4310 RetValExp = ER.
get();
4316 }
else if (!RetValExp && !HasDependentReturnType) {
4321 Diag(ReturnLoc, diag::err_constexpr_return_missing_expr)
4327 unsigned DiagID =
getLangOpts().C99 ? diag::ext_return_missing_expr
4328 : diag::warn_return_missing_expr;
4332 "Not in a FunctionDecl or ObjCMethodDecl?");
4333 bool IsMethod = FD ==
nullptr;
4336 Diag(ReturnLoc, DiagID) << ND << IsMethod;
4342 assert(RetValExp || HasDependentReturnType);
4343 QualType RetType = RelatedRetType.
isNull() ? FnRetType : RelatedRetType;
4356 Entity, NRInfo, RetValExp, SupressSimplerImplicitMoves);
4359 RetValExp->
getEndLoc(), RetValExp, RetType);
4370 if (!RelatedRetType.
isNull()) {
4381 CheckReturnValExpr(RetValExp, FnRetType, ReturnLoc, isObjCMethod, Attrs,
4390 RetValExp = ER.
get();
4397 if (
Result->getNRVOCandidate())
4408 Stmt *HandlerBlock) {
4411 CXXCatchStmt(CatchLoc, cast_or_null<VarDecl>(ExDecl), HandlerBlock);
4415class CatchHandlerType {
4417 LLVM_PREFERRED_TYPE(
bool)
4418 unsigned IsPointer : 1;
4420 friend struct llvm::DenseMapInfo<CatchHandlerType>;
4438 CatchHandlerType(
QualType QT,
bool IsPointer)
4439 : QT(QT), IsPointer(IsPointer) {}
4441 QualType underlying()
const {
return QT; }
4442 bool isPointer()
const {
return IsPointer; }
4444 friend bool operator==(
const CatchHandlerType &LHS,
4445 const CatchHandlerType &RHS) {
4447 if (LHS.IsPointer != RHS.IsPointer)
4450 return LHS.QT == RHS.QT;
4456template <>
struct DenseMapInfo<CatchHandlerType> {
4458 return DenseMapInfo<QualType>::getHashValue(
Base.underlying());
4462 const CatchHandlerType &RHS) {
4469class CatchTypePublicBases {
4470 const llvm::DenseMap<QualType, CXXCatchStmt *> &TypesToCheck;
4472 CXXCatchStmt *FoundHandler;
4473 QualType FoundHandlerType;
4474 QualType TestAgainstType;
4477 CatchTypePublicBases(
const llvm::DenseMap<QualType, CXXCatchStmt *> &
T,
4479 : TypesToCheck(
T), FoundHandler(
nullptr), TestAgainstType(QT) {}
4481 CXXCatchStmt *getFoundHandler()
const {
return FoundHandler; }
4482 QualType getFoundHandlerType()
const {
return FoundHandlerType; }
4484 bool operator()(
const CXXBaseSpecifier *S, CXXBasePath &) {
4487 const auto &M = TypesToCheck;
4488 auto I = M.find(Check);
4500 if (I->second->getCaughtType()->isPointerType() ==
4502 FoundHandler = I->second;
4503 FoundHandlerType = Check;
4515 const llvm::Triple &
T =
Context.getTargetInfo().getTriple();
4516 const bool IsOpenMPGPUTarget =
4523 if (IsOpenMPGPUTarget)
4524 targetDiag(TryLoc, diag::warn_try_not_valid_on_target) <<
T.str();
4532 Diag(TryLoc, diag::err_omp_simd_region_cannot_use_stmt) <<
"try";
4538 Diag(TryLoc, diag::err_mixing_cxx_try_seh_try) << 0;
4542 const unsigned NumHandlers = Handlers.size();
4543 assert(!Handlers.empty() &&
4544 "The parser shouldn't call this if there are no handlers.");
4546 llvm::DenseMap<QualType, CXXCatchStmt *> HandledBaseTypes;
4547 llvm::DenseMap<CatchHandlerType, CXXCatchStmt *> HandledTypes;
4548 for (
unsigned i = 0; i < NumHandlers; ++i) {
4555 if (i < NumHandlers - 1)
4569 QualType Underlying = HandlerCHT.underlying();
4571 if (!RD->hasDefinition())
4580 CatchTypePublicBases CTPB(HandledBaseTypes,
4582 if (RD->lookupInBases(CTPB, Paths)) {
4587 diag::warn_exception_caught_by_earlier_handler)
4590 diag::note_previous_exception_handler)
4602 auto R = HandledTypes.insert(
4607 diag::warn_exception_caught_by_earlier_handler)
4610 diag::note_previous_exception_handler)
4622 const llvm::Triple &
T =
Context.getTargetInfo().getTriple();
4623 const bool IsOpenMPGPUTarget =
4635 targetDiag(Loc, diag::err_exceptions_disabled) << (IsTry ?
"try" :
"throw");
4640 assert(TryBlock && Handler);
4667 Diag(TryLoc, diag::err_seh_try_outside_functions);
4670 if (!
Context.getTargetInfo().isSEHTrySupported())
4671 Diag(TryLoc, diag::err_seh_try_unsupported);
4678 assert(FilterExpr &&
Block);
4682 Diag(FilterExpr->
getExprLoc(), diag::err_filter_expression_integral)
4704 Scope *SEHTryParent = CurScope;
4706 SEHTryParent = SEHTryParent->
getParent();
4708 return StmtError(
Diag(Loc, diag::err_ms___leave_not_in___try));
4710 diag::DeferJumpKind::SEHLeave);
4722 QualifierLoc, NameInfo,
4740 unsigned NumParams) {
4758 assert(NumParams > 0 &&
"CapturedStmt requires context parameter");
4768 bool HasError =
false;
4777 if (
auto *BD = dyn_cast<BindingDecl>(CapVar)) {
4797 if (
auto *DD = dyn_cast<DecompositionDecl>(CapVar)) {
4798 if (!CapturedDecomposed.insert(DD).second) {
4831 if (
const auto *DD = dyn_cast<DecompositionDecl>(DSAVar))
4832 if (!DD->bindings().empty())
4833 DSAVar = *DD->bindings().begin();
4841 CaptureInits.push_back(
Init.get());
4846static std::optional<int>
4863 unsigned NumParams) {
4865 Diag(Loc, diag::err_sme_openmp_captured_region) << *ErrorIndex;
4898 unsigned OpenMPCaptureLevel) {
4900 Diag(Loc, diag::err_sme_openmp_captured_region) << *ErrorIndex;
4907 bool ContextIsFound =
false;
4908 unsigned ParamNum = 0;
4911 I != E; ++I, ++ParamNum) {
4912 if (I->second.isNull()) {
4913 assert(!ContextIsFound &&
4914 "null type has been found already for '__context' parameter");
4925 ContextIsFound =
true;
4935 assert(ContextIsFound &&
"no null type for '__context' parameter");
4936 if (!ContextIsFound) {
4967 Record->setInvalidDecl();
4993 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.
Result
Implement __builtin_bit_cast and related operations.
llvm::MachO::Target Target
llvm::MachO::Record Record
Defines the clang::Preprocessor interface.
static std::string toString(const clang::SanitizerSet &Sanitizers)
Produce a string containing comma-separated names of sanitizers in Sanitizers set.
This file declares semantic analysis for CUDA constructs.
This file declares semantic analysis for HLSL 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 CheckRedundantDeferStmt(Sema &S, Stmt *Body)
static void CheckLoopBody(Sema &S, Expr *CondExpr, Stmt *Body)
static Scope * FindLabeledBreakContinueScope(Sema &S, Scope *CurScope, SourceLocation KWLoc, LabelDecl *Target, SourceLocation LabelLoc, bool IsContinue)
static bool EqEnumVals(const std::pair< llvm::APSInt, EnumConstantDecl * > &lhs, const std::pair< llvm::APSInt, EnumConstantDecl * > &rhs)
EqEnumVals - Comparison preficate for uniqing enumeration values.
static std::optional< int > isOpenMPCapturedRegionInArmSMEFunction(Sema const &S, CapturedRegionKind Kind)
static bool hasDeducedReturnType(FunctionDecl *FD)
Determine whether the declared return type of the specified function contains 'auto'.
static bool DiagnoseSwitchCaseInExpansionStmt(Sema &S, SourceLocation KwLoc, bool IsDefault)
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 CheckJumpOutOfSEHFinallyOrDefer(Sema &S, SourceLocation Loc, const Scope &DestScope, unsigned DeferJumpKind)
static StringRef GetDeferKeywordSpelling(Sema &S, SourceLocation DeferLoc)
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.
Defines the Objective-C statement AST node classes.
Defines the clang::TypeLoc interface and its subclasses.
Allows QualTypes to be sorted and hence used in maps and sets.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
QualType getLValueReferenceType(QualType T, bool SpelledAsLValue=true) const
Return the uniqued reference to the type for an lvalue reference to the specified type.
uint64_t getTypeSize(QualType T) const
Return the size of the specified (complete) type T, in bits.
CanQualType getCanonicalTagType(const TagDecl *TD) const
static bool hasSameUnqualifiedType(QualType T1, QualType T2)
Determine whether the given types are equivalent after cvr-qualifiers have been removed.
Represents an array type, per C99 6.7.5.2 - Array Declarators.
Attr - This represents one attribute.
SourceLocation getLocation() const
SourceRange getRange() const
static AttributedStmt * Create(const ASTContext &C, SourceLocation Loc, ArrayRef< const Attr * > Attrs, Stmt *SubStmt)
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression which will be evaluated if the condition evaluates to false; ...
OpaqueValueExpr * getOpaqueValue() const
getOpaqueValue - Return the opaque value placeholder.
A builtin binary operation expression such as "x + y" or "x <= y".
SourceLocation getExprLoc() const
BreakStmt - This represents a break.
CStyleCastExpr - An explicit cast in C (C99 6.5.4) or a C-style cast in C++ (C++ [expr....
BasePaths - Represents the set of paths from a derived class to one of its (direct or indirect) bases...
void setOrigin(const CXXRecordDecl *Rec)
bool isAmbiguous(CanQualType BaseType) const
Determine whether the path from the most-derived type to the given base type is ambiguous (i....
QualType getType() const
Retrieves the type of the base class.
AccessSpecifier getAccessSpecifier() const
Returns the access specifier for this base specifier.
Represents binding an expression to a temporary.
CXXCatchStmt - This represents a C++ catch block.
SourceLocation getBeginLoc() const LLVM_READONLY
VarDecl * getExceptionDecl() const
QualType getCaughtType() const
Represents a call to a C++ constructor.
Represents a C++ conversion function within a class.
CXXForRangeStmt - This represents C++0x [stmt.ranged]'s ranged for statement, represented as 'for (ra...
DeclStmt * getBeginStmt()
DeclStmt * getRangeStmt()
Represents an explicit C++ type conversion that uses "functional" notation (C++ [expr....
Represents a call to a member function that may be written either with member call syntax (e....
A call to an overloaded operator written using operator syntax.
Represents a C++ struct/union/class.
static CXXRecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl=nullptr)
An expression "T()" which creates an rvalue of a non-class type T.
Represents a C++ nested-name-specifier or a global scope specifier.
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context.
static CXXTryStmt * Create(const ASTContext &C, SourceLocation tryLoc, CompoundStmt *tryBlock, ArrayRef< Stmt * > handlers)
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
static CanQual< Type > CreateUnsafe(QualType Other)
Represents the body of a CapturedStmt, and serves as its DeclContext.
static DeclContext * castToDeclContext(const CapturedDecl *D)
void setContextParam(unsigned i, ImplicitParamDecl *P)
void setParam(unsigned i, ImplicitParamDecl *P)
static CapturedDecl * Create(ASTContext &C, DeclContext *DC, unsigned NumParams)
Describes the capture of either a variable, or 'this', or variable-length array type.
This captures a statement into a function.
Stmt * getCapturedStmt()
Retrieve the statement being captured.
static CapturedStmt * Create(const ASTContext &Context, Stmt *S, CapturedRegionKind Kind, ArrayRef< Capture > Captures, ArrayRef< Expr * > CaptureInits, CapturedDecl *CD, RecordDecl *RD)
CaseStmt - Represent a case statement.
static CaseStmt * Create(const ASTContext &Ctx, Expr *lhs, Expr *rhs, SourceLocation caseLoc, SourceLocation ellipsisLoc, SourceLocation colonLoc)
Build a case statement.
CastExpr - Base class for type casts, including both implicit casts (ImplicitCastExpr) and explicit c...
CastKind getCastKind() const
CompoundStmt - This represents a group of statements like { stmt stmt }.
static CompoundStmt * Create(const ASTContext &C, ArrayRef< Stmt * > Stmts, FPOptionsOverride FPFeatures, SourceLocation LB, SourceLocation RB)
Expr * getFalseExpr() const
getFalseExpr - Return the subexpression representing the value of the expression if the condition eva...
Expr * getCond() const
getCond - Return the expression representing the condition for the ?
Expr * getTrueExpr() const
getTrueExpr - Return the subexpression representing the value of the expression if the condition eval...
ConstEvaluatedExprVisitor - This class visits 'const Expr *'s.
Represents the canonical version of C arrays with a specified constant size.
ContinueStmt - This represents a continue.
DeclContext - This is used only as base class of specific decl types that can act as declaration cont...
DeclContext * getParent()
getParent - Returns the containing DeclContext.
bool isFileContext() const
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
void addDecl(Decl *D)
Add the declaration D into this context.
bool isFunctionOrMethod() const
Returns true if this DeclContext is a function, Objective-C method, or block, or a DeclContext that c...
void addHiddenDecl(Decl *D)
Add the declaration D to this context without modifying any lookup tables.
bool isExpansionStmt() const
bool isSingleDecl() const
A reference to a declared variable, function, enum, etc.
SourceLocation getLocation() const
DeclStmt - Adaptor class for mixing declarations with statements and expressions.
bool isSingleDecl() const
isSingleDecl - This method returns true if this DeclStmt refers to a single Decl.
const Decl * getSingleDecl() const
SourceLocation getBeginLoc() const LLVM_READONLY
Decl - This represents one declaration (or definition), e.g.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
void markUsed(ASTContext &C)
Mark the declaration used, in the sense of odr-use.
static Decl * castFromDeclContext(const DeclContext *)
bool isInvalidDecl() const
SourceLocation getLocation() const
void setImplicit(bool I=true)
void setLocation(SourceLocation L)
DeclContext * getDeclContext()
SourceLocation getTypeSpecEndLoc() const
SourceLocation getTypeSpecStartLoc() const
SourceLocation getBeginLoc() const LLVM_READONLY
TypeSourceInfo * getTypeSourceInfo() const
SourceLocation getDefaultLoc() const
static DeferStmt * Create(ASTContext &Context, SourceLocation DeferLoc, Stmt *Body)
bool isIgnored(unsigned DiagID, SourceLocation Loc) const
Determine whether the diagnostic is known to be ignored.
DoStmt - This represents a 'do/while' stmt.
EnumDecl * getCanonicalDecl() override
Retrieves the "canonical" declaration of the given declaration.
bool isClosed() const
Returns true if this enum is either annotated with enum_extensibility(closed) or isn't annotated with...
EvaluatedExprVisitor - This class visits 'Expr *'s.
This represents one expression.
bool EvaluateAsInt(EvalResult &Result, const ASTContext &Ctx, SideEffectsKind AllowSideEffects=SE_NoSideEffects, bool InConstantContext=false) const
EvaluateAsInt - Return true if this is a constant which we can fold and convert to an integer,...
@ SE_AllowSideEffects
Allow any unmodeled side effect.
Expr * IgnoreParenCasts() LLVM_READONLY
Skip past any parentheses and casts which might surround this expression until reaching a fixed point...
bool isUnusedResultAWarning(const Expr *&WarnExpr, SourceLocation &Loc, SourceRange &R1, SourceRange &R2, ASTContext &Ctx) const
isUnusedResultAWarning - Return true if this immediate expression should be warned about if the resul...
bool isValueDependent() const
Determines whether the value of this expression depends on.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
llvm::APSInt EvaluateKnownConstInt(const ASTContext &Ctx) const
EvaluateKnownConstInt - Call EvaluateAsRValue and return the folded integer.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
bool containsErrors() const
Whether this expression contains subexpressions which had errors.
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
Decl * getReferencedDeclOfCallee()
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
std::optional< llvm::APSInt > getIntegerConstantExpr(const ASTContext &Ctx, bool AllowRelaxedEval=false) const
isIntegerConstantExpr - Return the value if this expression is a valid integer constant expression.
Expr * IgnoreImpCasts() LLVM_READONLY
Skip past any implicit casts which might surround this expression until reaching a fixed point.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool isKnownToHaveBooleanValue(bool Semantic=true) const
isKnownToHaveBooleanValue - Return true if this is an integer expression that is known to return 0 or...
Represents difference between two FPOptions values.
FPOptionsOverride getChangesFrom(const FPOptions &Base) const
Return difference with the given option set.
Represents a member of a struct/union/class.
static FixItHint CreateReplacement(CharSourceRange RemoveRange, StringRef Code)
Create a code modification hint that replaces the given source range with the given code string.
static FixItHint CreateRemoval(CharSourceRange RemoveRange)
Create a code modification hint that removes the given source range.
static FixItHint CreateInsertion(SourceLocation InsertionLoc, StringRef Code, bool BeforePreviousInsertions=false)
Create a code modification hint that inserts the given code string at a specific location.
ForStmt - This represents a 'for (init;cond;inc)' stmt.
SourceLocation getRParenLoc() const
SourceLocation getBeginLoc() const
FullExpr - Represents a "full-expression" node.
Represents a function declaration or definition.
const ParmVarDecl * getParamDecl(unsigned i) const
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
void setUsesSEHTry(bool UST)
bool isNoReturn() const
Determines whether this function is known to be 'noreturn', through an attribute on its declaration o...
QualType getReturnType() const
FunctionTemplateDecl * getPrimaryTemplate() const
Retrieve the primary template that this function template specialization either specializes or was in...
const TemplateArgumentList * getTemplateSpecializationArgs() const
Retrieve the template arguments used to produce this function template specialization from the primar...
bool isConstexpr() const
Whether this is a (C++11) constexpr function or constexpr constructor.
bool isMain() const
Determines whether this function is "main", which is the entry point into an executable program.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isOverloadedOperator() const
Whether this function declaration represents an C++ overloaded operator, e.g., "operator+".
OverloadedOperatorKind getOverloadedOperator() const
getOverloadedOperator - Which C++ overloaded operator this function represents, if any.
QualType getDeclaredReturnType() const
Get the declared return type, which may differ from the actual return type if the return type is dedu...
Represents a prototype with parameter type info, e.g.
Declaration of a template function.
FunctionType - C99 6.7.5.3 - Function Declarators.
static StringRef getNameForCallConv(CallingConv CC)
bool getNoReturnAttr() const
Determine whether this function type includes the GNU noreturn attribute.
QualType getReturnType() const
GotoStmt - This represents a direct goto.
One of these records is kept for each identifier that is lexed.
IdentifierInfo & get(StringRef Name)
Return the identifier token info for the specified named identifier.
static IfStmt * Create(const ASTContext &Ctx, SourceLocation IL, IfStatementKind Kind, Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LPL, SourceLocation RPL, Stmt *Then, SourceLocation EL=SourceLocation(), Stmt *Else=nullptr)
Create an IfStmt.
ImplicitCastExpr - Allows us to explicitly represent implicit type conversions, which have no direct ...
static ImplicitCastExpr * Create(const ASTContext &Context, QualType T, CastKind Kind, Expr *Operand, const CXXCastPath *BasePath, ExprValueKind Cat, FPOptionsOverride FPO)
static ImplicitParamDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, ImplicitParamKind ParamKind)
Create implicit parameter.
IndirectGotoStmt - This represents an indirect goto.
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
Describes an entity that is being initialized.
static InitializedEntity InitializeResult(SourceLocation ReturnLoc, QualType Type)
Create the initialization entity for the result of a function.
static InitializedEntity InitializeRelatedResult(ObjCMethodDecl *MD, QualType Type)
Create the initialization entity for a related result.
unsigned allocateManglingNumber() const
static InitializedEntity InitializeVariable(VarDecl *Var)
Create the initialization entity for a variable.
static InitializedEntity InitializeParameter(ASTContext &Context, ParmVarDecl *Parm)
Create the initialization entity for a parameter.
static IntegerLiteral * Create(const ASTContext &C, const llvm::APInt &V, QualType type, SourceLocation l)
Returns a new integer literal with value 'V' and type 'type'.
Represents the declaration of a label.
void setLocStart(SourceLocation L)
LabelStmt * getStmt() const
void setStmt(LabelStmt *T)
bool isMSAsmLabel() const
LabelStmt - Represents a label, which has a substatement.
Represents the results of name lookup.
bool empty() const
Return true if no decls were found.
SourceLocation getKwLoc() const
Representation of a Microsoft __if_exists or __if_not_exists statement with a dependent name.
Represents a prvalue temporary that is written into memory so that a reference can bind to it.
Expr * getSubExpr() const
Retrieve the temporary-generating subexpression whose value will be materialized into a glvalue.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
This represents a decl that may have a name.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const
Determine if the declaration obeys the reserved identifier rules of the given language.
A C++ nested-name-specifier augmented with source location information.
NullStmt - This is the null statement ";": C99 6.8.3p3.
An expression that sends a message to the given Objective-C object or class.
ObjCMethodDecl - Represents an instance or class method declaration.
Represents a pointer to an Objective C object.
Expr * getSourceExpr() const
The source expression of an opaque value expression is the expression which originally generated the ...
OverloadCandidateSet - A set of overload candidates, used in C++ overload resolution (C++ 13....
@ CSK_Normal
Normal lookup.
void NoteCandidates(PartialDiagnosticAt PA, Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef< Expr * > Args, StringRef Opc="", SourceLocation Loc=SourceLocation(), llvm::function_ref< bool(OverloadCandidate &)> Filter=[](OverloadCandidate &) { return true;})
When overload resolution fails, prints diagnostic messages containing the candidates in the candidate...
static FindResult find(Expr *E)
Finds the overloaded expression in the given expression E of OverloadTy.
const Expr * getSubExpr() const
Represents a parameter to a function.
ParsedAttributes - A collection of parsed attributes.
Wrapper for source info for pointers.
SourceLocation getStarLoc() const
IdentifierTable & getIdentifierTable()
StringRef getLastMacroWithSpelling(SourceLocation Loc, ArrayRef< TokenValue > Tokens) const
Return the name of the macro defined before Loc that has spelling Tokens.
PseudoObjectExpr - An expression which accesses a pseudo-object l-value.
ArrayRef< Expr * > semantics()
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType withConst() const
bool isTriviallyCopyConstructibleType(const ASTContext &Context) const
Return true if this is a trivially copyable type.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
unsigned getLocalCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers local to this particular QualType instan...
bool isConstQualified() const
Determine whether this type is const-qualified.
@ OCL_Strong
Assigning into this object requires the old value to be released and the new value to be retained.
Represents a struct/union/class.
static RecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, RecordDecl *PrevDecl=nullptr)
virtual void completeDefinition()
Note that the definition of this type is now complete.
void setCapturedRecord()
Mark the record as a record for captured variables in CapturedStmt construct.
ReturnStmt - This represents a return, optionally of an expression: return; return 4;.
static ReturnStmt * Create(const ASTContext &Ctx, SourceLocation RL, Expr *E, const VarDecl *NRVOCandidate)
Create a return statement.
static SEHExceptStmt * Create(const ASTContext &C, SourceLocation ExceptLoc, Expr *FilterExpr, Stmt *Block)
static SEHFinallyStmt * Create(const ASTContext &C, SourceLocation FinallyLoc, Stmt *Block)
Represents a __leave statement.
static SEHTryStmt * Create(const ASTContext &C, bool isCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)
Scope - A scope is a transient data structure that is used while parsing the program.
unsigned getDepth() const
Returns the depth of this scope. The translation-unit has scope depth 0.
bool Contains(const Scope &rhs) const
Returns if rhs has a higher scope depth than this.
LabelDecl * getPrecedingLabel() const
Get the label that precedes this scope.
Scope * getContinueParent()
getContinueParent - Return the closest scope that a continue statement would be affected by.
bool isLoopScope() const
Return true if this scope is a loop.
bool isSEHTryScope() const
Determine whether this scope is a SEH '__try' block.
Scope * getBreakParent()
getBreakParent - Return the closest scope that a break statement would be affected by.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
bool isBreakOrContinueScope() const
Determine whether this is a scope which can have 'break' or 'continue' statements embedded into it.
bool isFunctionScope() const
isFunctionScope() - Return true if this scope is a function scope.
bool isOpenACCComputeConstructScope() const
Determine whether this scope is the statement associated with an OpenACC Compute construct directive.
bool isOpenMPLoopScope() const
Determine whether this scope is a loop having OpenMP loop directive attached.
@ SwitchScope
This is a scope that corresponds to a switch statement.
A generic diagnostic builder for errors which may or may not be deferred.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
SemaDiagnosticBuilder DiagCompat(SourceLocation Loc, unsigned CompatDiagId)
Emit a compatibility diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
CUDAFunctionTarget CurrentTarget()
Gets the CUDA target for the current context.
SemaDiagnosticBuilder DiagIfDeviceCode(SourceLocation Loc, unsigned DiagID)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as device c...
StmtResult ActOnObjCForCollectionStmt(SourceLocation ForColLoc, Stmt *First, Expr *collection, SourceLocation RParenLoc)
StmtResult FinishObjCForCollectionStmt(Stmt *ForCollection, Stmt *Body)
FinishObjCForCollectionStmt - Attach the body to a objective-C foreach statement.
bool inferObjCARCLifetime(ValueDecl *decl)
void ActOnOpenMPLoopInitialization(SourceLocation ForLoc, Stmt *Init)
Check if the current region is an OpenMP loop region and if it is, mark loop control variable,...
void setOpenMPCaptureKind(FieldDecl *FD, const ValueDecl *D, unsigned Level)
Sets OpenMP capture kind (OMPC_private, OMPC_firstprivate, OMPC_map etc.) for FD based on DSA for the...
std::pair< VarDecl *, Expr * > get() const
RAII class used to determine whether SFINAE has trapped any errors that occur during template argumen...
Sema - This implements semantic analysis and AST building for C.
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)
Package the given type and TSI into a ParsedType.
SmallVector< Scope *, 2 > CurrentSEHFinally
Stack of active SEH __finally scopes. Can be empty.
LocalInstantiationScope * CurrentInstantiationScope
The current instantiation scope used to store local variables.
Scope * getCurScope() const
Retrieve the parser's current scope.
StmtResult ActOnBreakStmt(SourceLocation BreakLoc, Scope *CurScope, LabelDecl *Label, SourceLocation LabelLoc)
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 BuildCXXForRangeRangeVar(Scope *S, Expr *Range, QualType Type, bool IsConstexpr=false)
Build the range variable of a range-based for loop or iterating expansion statement and return its De...
StmtResult ActOnSEHLeaveStmt(SourceLocation Loc, Scope *CurScope)
llvm::DenseMap< const EnumDecl *, llvm::SmallVector< llvm::APSInt > > AssignEnumCache
A cache of enumerator values for enums checked by -Wassign-enum.
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...
bool checkAndRewriteMustTailAttr(Stmt *St, const Attr &MTA)
Check whether the given statement can have musttail applied to it, issuing a diagnostic and returning...
StmtResult ActOnContinueStmt(SourceLocation ContinueLoc, Scope *CurScope, LabelDecl *Label, SourceLocation LabelLoc)
StmtResult ActOnGotoStmt(SourceLocation GotoLoc, SourceLocation LabelLoc, LabelDecl *TheDecl)
StmtResult ActOnReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, Scope *CurScope)
void setFunctionHasBranchIntoScope()
ExprResult ActOnCaseExpr(SourceLocation CaseLoc, ExprResult Val)
StmtResult ActOnExprStmt(ExprResult Arg, bool DiscardedValue=true)
AssignConvertType CheckSingleAssignmentConstraints(QualType LHSType, ExprResult &RHS, bool Diagnose=true, bool DiagnoseCFAudited=false, bool ConvertRHS=true)
Check assignment constraints for an assignment of RHS to LHSType.
StmtResult BuildIfStmt(SourceLocation IfLoc, IfStatementKind StatementKind, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc, Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal)
FunctionDecl * getCurFunctionDecl(bool AllowLambda=false) const
Returns a pointer to the innermost enclosing function, or nullptr if the current context is not insid...
ExprResult PerformContextualImplicitConversion(SourceLocation Loc, Expr *FromE, ContextualImplicitConverter &Converter)
Perform a contextual implicit conversion.
ExprResult UsualUnaryConversions(Expr *E)
UsualUnaryConversions - Performs various conversions that are common to most operators (C99 6....
void DiagnoseCommaOperator(const Expr *LHS, SourceLocation Loc)
Look for instances where it is likely the comma operator is confused with another operator.
void DiagnoseExceptionUse(SourceLocation Loc, bool IsTry)
ExprResult CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond)
bool DiagIfReachable(SourceLocation Loc, ArrayRef< const Stmt * > Stmts, const PartialDiagnostic &PD)
Conditionally issue a diagnostic based on the statements's reachability analysis.
void FinalizeDeclaration(Decl *D)
FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform any semantic actions neces...
void ActOnCapturedRegionError()
DeclGroupPtrTy ConvertDeclToDeclGroup(Decl *Ptr, Decl *OwnedType=nullptr)
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ASTContext & getASTContext() const
std::unique_ptr< sema::FunctionScopeInfo, PoppedFunctionScopeDeleter > PoppedFunctionScopePtr
ExprResult BuildUnaryOp(Scope *S, SourceLocation OpLoc, UnaryOperatorKind Opc, Expr *Input, bool IsAfterAmp=false)
void PopExpressionEvaluationContext()
StmtResult ActOnSEHTryBlock(bool IsCXXTry, SourceLocation TryLoc, Stmt *TryBlock, Stmt *Handler)
ExprResult ImpCastExprToType(Expr *E, QualType Type, CastKind CK, ExprValueKind VK=VK_PRValue, const CXXCastPath *BasePath=nullptr, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
ImpCastExprToType - If Expr is not of type 'Type', insert an implicit cast.
FieldDecl * BuildCaptureField(RecordDecl *RD, const sema::Capture &Capture, bool IsOpenMP=false)
Build a FieldDecl suitable to hold the given capture.
ObjCMethodDecl * getCurMethodDecl()
getCurMethodDecl - If inside of a method body, this returns a pointer to the method decl for the meth...
DeclRefExpr * BuildDeclRefExpr(ValueDecl *D, QualType Ty, ExprValueKind VK, SourceLocation Loc, const CXXScopeSpec *SS=nullptr)
ExprResult CheckConvertedConstantExpression(Expr *From, QualType T, llvm::APSInt &Value, CCEKind CCE)
void setFunctionHasIndirectGoto()
ExprResult BuildCaptureInit(const sema::Capture &Capture, SourceLocation ImplicitCaptureLoc, bool IsOpenMPMapping=false)
Initialize the given capture with a suitable expression.
StmtResult ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch, Stmt *Body)
NamedReturnInfo getNamedReturnInfo(Expr *&E, SimplerImplicitMoveMode Mode=SimplerImplicitMoveMode::Normal)
Determine whether the given expression might be move-eligible or copy-elidable in either a (co_)retur...
void DiagnoseUnusedExprResult(const Stmt *S, unsigned DiagID)
DiagnoseUnusedExprResult - If the statement passed in is an expression whose result is unused,...
FPOptions & getCurFPFeatures()
Sema(Preprocessor &pp, ASTContext &ctxt, ASTConsumer &consumer, TranslationUnitKind TUKind=TU_Complete, CodeCompleteConsumer *CompletionConsumer=nullptr)
@ UPPC_Expression
An arbitrary expression.
const LangOptions & getLangOpts() const
PoppedFunctionScopePtr PopFunctionScopeInfo(const sema::AnalysisBasedWarnings::Policy *WP=nullptr, Decl *D=nullptr, QualType BlockType=QualType())
Pop a function (or block or lambda or captured region) scope from the stack.
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....
TypeLoc getReturnTypeLoc(FunctionDecl *FD) const
StmtResult ActOnExprStmtError()
const VarDecl * getCopyElisionCandidate(NamedReturnInfo &Info, QualType ReturnType)
Updates given NamedReturnInfo's move-eligible and copy-elidable statuses, considering the function re...
NamedDecl * getCurFunctionOrMethodDecl() const
getCurFunctionOrMethodDecl - Return the Decl for the current ObjC method or C function we're in,...
StmtResult ActOnNullStmt(SourceLocation SemiLoc, bool HasLeadingEmptyMacro=false)
RecordDecl * CreateCapturedStmtRecordDecl(CapturedDecl *&CD, SourceLocation Loc, unsigned NumParams)
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope, CapturedRegionKind Kind, unsigned NumParams)
sema::FunctionScopeInfo * getCurFunction() const
void PushCompoundScope(bool IsStmtExpr)
DeclGroupPtrTy BuildDeclaratorGroup(MutableArrayRef< Decl * > Group)
BuildDeclaratorGroup - convert a list of declarations into a declaration group, performing any necess...
void DiagnoseAssignmentEnum(QualType DstType, QualType SrcType, Expr *SrcExpr)
DiagnoseAssignmentEnum - Warn if assignment to enum is a constant integer not in the range of enum va...
StmtResult ActOnEndOfDeferStmt(Stmt *Body, Scope *CurScope)
ExprResult ActOnCoawaitExpr(Scope *S, SourceLocation KwLoc, Expr *E)
bool findMacroSpelling(SourceLocation &loc, StringRef name)
Looks through the macro-expansion chain for the given location, looking for a macro expansion with th...
void DiagnoseEmptyStmtBody(SourceLocation StmtLoc, const Stmt *Body, unsigned DiagID)
Emit DiagID if statement located on StmtLoc has a suspicious null statement as a Body,...
void DiagnoseEmptyLoopBody(const Stmt *S, const Stmt *PossibleBody)
Warn if a for/while loop statement S, which is followed by PossibleBody, has a suspicious null statem...
ExprResult DefaultLvalueConversion(Expr *E)
void ApplyForRangeOrExpansionStatementLifetimeExtension(VarDecl *RangeVar, ArrayRef< MaterializeTemporaryExpr * > Temporaries)
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name)
Retrieves the declaration name from a parsed unqualified-id.
void ActOnStartOfDeferStmt(SourceLocation DeferLoc, Scope *CurScope)
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
StmtResult ActOnCapScopeReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, NamedReturnInfo &NRInfo, bool SupressSimplerImplicitMoves)
ActOnCapScopeReturnStmt - Utility routine to type-check return statements for capturing scopes.
StmtResult ActOnCapturedRegionEnd(Stmt *S)
StmtResult ActOnForStmt(SourceLocation ForLoc, SourceLocation LParenLoc, Stmt *First, ConditionResult Second, FullExprArg Third, SourceLocation RParenLoc, Stmt *Body)
StmtResult ActOnIndirectGotoStmt(SourceLocation GotoLoc, SourceLocation StarLoc, Expr *DestExp)
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
SourceManager & getSourceManager() const
ExprResult PerformMoveOrCopyInitialization(const InitializedEntity &Entity, const NamedReturnInfo &NRInfo, Expr *Value, bool SupressSimplerImplicitMoves=false)
Perform the initialization of a potentially-movable value, which is the result of return value.
void ActOnInitializerError(Decl *Dcl)
ActOnInitializerError - Given that there was an error parsing an initializer for the given declaratio...
StmtResult ActOnCXXForRangeStmt(Scope *S, SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *InitStmt, Stmt *LoopVar, SourceLocation ColonLoc, Expr *Collection, SourceLocation RParenLoc, BuildForRangeKind Kind, ArrayRef< MaterializeTemporaryExpr * > LifetimeExtendTemps={})
ActOnCXXForRangeStmt - Check and build a C++11 for-range statement.
bool isSFINAEContext() const
StmtResult BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp, bool AllowRecovery=false)
ExprResult ActOnBinOp(Scope *S, SourceLocation TokLoc, tok::TokenKind Kind, Expr *LHSExpr, Expr *RHSExpr)
Binary Operators. 'Tok' is the token for the operator.
void PushCapturedRegionScope(Scope *RegionScope, CapturedDecl *CD, RecordDecl *RD, CapturedRegionKind K, unsigned OpenMPCaptureLevel=0)
void setFunctionHasMustTail()
void setFunctionHasBranchProtectedScope()
StmtResult ActOnFinishSEHFinallyBlock(SourceLocation Loc, Stmt *Block)
StmtResult BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc, Stmt *InitStmt, SourceLocation ColonLoc, Stmt *RangeDecl, Stmt *Begin, Stmt *End, Expr *Cond, Expr *Inc, Stmt *LoopVarDecl, SourceLocation RParenLoc, BuildForRangeKind Kind, ArrayRef< MaterializeTemporaryExpr * > LifetimeExtendTemps={})
BuildCXXForRangeStmt - Build or instantiate a C++11 for-range statement.
StmtResult ActOnDoStmt(SourceLocation DoLoc, Stmt *Body, SourceLocation WhileLoc, SourceLocation CondLParen, Expr *Cond, SourceLocation CondRParen)
StmtResult ActOnStartOfSwitchStmt(SourceLocation SwitchLoc, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc)
ExprResult VerifyIntegerConstantExpression(Expr *E, llvm::APSInt *Result, VerifyICEDiagnoser &Diagnoser, AllowFoldKind CanFold=AllowFoldKind::No)
VerifyIntegerConstantExpression - Verifies that an expression is an ICE, and reports the appropriate ...
VarDecl * BuildForRangeVarDecl(SourceLocation Loc, QualType Type, IdentifierInfo *Name, bool IsConstexpr)
Helper used by the expansion statements and for-range code to build a variable declaration for e....
StmtResult ActOnMSDependentExistsStmt(SourceLocation KeywordLoc, bool IsIfExists, CXXScopeSpec &SS, UnqualifiedId &Name, Stmt *Nested)
@ PotentiallyEvaluated
The current expression is potentially evaluated at run time, which means that code may be generated t...
@ ImmediateFunctionContext
In addition of being constant evaluated, the current expression occurs in an immediate function conte...
StmtResult ActOnSEHExceptBlock(SourceLocation Loc, Expr *FilterExpr, Stmt *Block)
void ActOnAfterCompoundStatementLeadingPragmas()
StmtResult ActOnDeclStmt(DeclGroupPtrTy Decl, SourceLocation StartLoc, SourceLocation EndLoc)
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
void ActOnFields(Scope *S, SourceLocation RecLoc, Decl *TagDecl, ArrayRef< Decl * > Fields, SourceLocation LBrac, SourceLocation RBrac, const ParsedAttributesView &AttrList)
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
void DiscardCleanupsInEvaluationContext()
SmallVector< ExpressionEvaluationContextRecord, 8 > ExprEvalContexts
A stack of expression evaluation contexts.
void PushDeclContext(Scope *S, DeclContext *DC)
Set the current declaration context until it gets popped.
StmtResult ActOnAttributedStmt(const ParsedAttributes &AttrList, Stmt *SubStmt)
SourceManager & SourceMgr
DiagnosticsEngine & Diags
void ActOnStartSEHFinallyBlock()
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
void ActOnAbortSEHFinallyBlock()
friend class InitializationSequence
void diagnoseIgnoredQualifiers(unsigned DiagID, unsigned Quals, SourceLocation FallbackLoc, SourceLocation ConstQualLoc=SourceLocation(), SourceLocation VolatileQualLoc=SourceLocation(), SourceLocation RestrictQualLoc=SourceLocation(), SourceLocation AtomicQualLoc=SourceLocation(), SourceLocation UnalignedQualLoc=SourceLocation())
void ActOnDeferStmtError(Scope *CurScope)
QualType SubstAutoTypeDependent(QualType TypeWithAuto)
@ BFRK_Check
Determining whether a for-range statement could be built.
@ BFRK_Build
Initial building of a for-range statement.
@ BFRK_Rebuild
Instantiation or recovery rebuild of a for-range statement.
StmtResult ActOnCXXCatchBlock(SourceLocation CatchLoc, Decl *ExDecl, Stmt *HandlerBlock)
ActOnCXXCatchBlock - Takes an exception declaration and a handler block and creates a proper catch ha...
void ActOnCaseStmtBody(Stmt *CaseStmt, Stmt *SubStmt)
ActOnCaseStmtBody - This installs a statement as the body of a case.
void AddInitializerToDecl(Decl *dcl, Expr *init, bool DirectInit)
AddInitializerToDecl - Adds the initializer Init to the declaration dcl.
bool DiagnoseAssignmentResult(AssignConvertType ConvTy, SourceLocation Loc, QualType DstType, QualType SrcType, Expr *SrcExpr, AssignmentAction Action, bool *Complained=nullptr)
DiagnoseAssignmentResult - Emit a diagnostic, if required, for the assignment conversion type specifi...
SemaDiagnosticBuilder targetDiag(SourceLocation Loc, unsigned DiagID, const FunctionDecl *FD=nullptr)
ExprResult CreateRecoveryExpr(SourceLocation Begin, SourceLocation End, ArrayRef< Expr * > SubExprs, QualType T=QualType())
Attempts to produce a RecoveryExpr after some AST node cannot be created.
StmtResult ActOnIfStmt(SourceLocation IfLoc, IfStatementKind StatementKind, SourceLocation LParenLoc, Stmt *InitStmt, ConditionResult Cond, SourceLocation RParenLoc, Stmt *ThenVal, SourceLocation ElseLoc, Stmt *ElseVal)
std::string getTemplateArgumentBindingsText(const TemplateParameterList *Params, const TemplateArgumentList &Args)
Produces a formatted string that describes the binding of template parameters to template arguments.
ExprResult ActOnUnaryExprOrTypeTraitExpr(SourceLocation OpLoc, UnaryExprOrTypeTrait ExprKind, bool IsType, void *TyOrEx, SourceRange ArgRange)
ActOnUnaryExprOrTypeTraitExpr - Handle sizeof(type) and sizeof expr and the same for alignof and __al...
ForRangeStatus BuildForRangeBeginEndCall(SourceLocation Loc, SourceLocation RangeLoc, const DeclarationNameInfo &NameInfo, LookupResult &MemberLookup, OverloadCandidateSet *CandidateSet, Expr *Range, ExprResult *CallExpr)
Build a call to 'begin' or 'end' for a C++11 for-range statement.
sema::CompoundScopeInfo & getCurCompoundScope() const
TemplateDeductionResult DeduceAutoType(TypeLoc AutoTypeLoc, Expr *Initializer, QualType &Result, sema::TemplateDeductionInfo &Info, bool DependentDeduction=false, bool IgnoreConstraints=false, TemplateSpecCandidateSet *FailedTSC=nullptr)
Deduce the type for an auto type-specifier (C++11 [dcl.spec.auto]p6)
void ActOnFinishOfCompoundStmt()
StmtResult ActOnCompoundStmt(SourceLocation L, SourceLocation R, ArrayRef< Stmt * > Elts, bool isStmtExpr)
bool IsValueInFlagEnum(const EnumDecl *ED, const llvm::APInt &Val, bool AllowMask) const
IsValueInFlagEnum - Determine if a value is allowed as part of a flag enum.
StmtResult ActOnLabelStmt(SourceLocation IdentLoc, LabelDecl *TheDecl, SourceLocation ColonLoc, Stmt *SubStmt)
StmtResult ActOnCXXTryBlock(SourceLocation TryLoc, Stmt *TryBlock, ArrayRef< Stmt * > Handlers)
ActOnCXXTryBlock - Takes a try compound-statement and a number of handlers and creates a try statemen...
OpaquePtr< DeclGroupRef > DeclGroupPtrTy
void ActOnDependentForRangeInitializer(VarDecl *LoopVar, BuildForRangeKind BFRK)
Set the type of a for-range declaration whose for-range or expansion initialiser is dependent.
StmtResult ActOnDefaultStmt(SourceLocation DefaultLoc, SourceLocation ColonLoc, Stmt *SubStmt, Scope *CurScope)
StmtResult ActOnCaseStmt(SourceLocation CaseLoc, ExprResult LHS, SourceLocation DotDotDotLoc, ExprResult RHS, SourceLocation ColonLoc)
ForRangeBeginEndInfo BuildCXXForRangeBeginEndVars(Scope *S, VarDecl *RangeVar, SourceLocation ColonLoc, SourceLocation CoawaitLoc, ArrayRef< MaterializeTemporaryExpr * > LifetimeExtendTemps, BuildForRangeKind Kind, bool IsConstexpr, StmtResult *RebuildResult=nullptr, llvm::function_ref< StmtResult()> RebuildWithDereference={}, IdentifierInfo *BeginName=nullptr, IdentifierInfo *EndName=nullptr)
Determine begin-expr and end-expr and build variable declarations for them as per [stmt....
SmallVector< std::pair< Scope *, SourceLocation >, 2 > CurrentDefer
Stack of '_Defer' statements that are currently being parsed, as well as the locations of their '_Def...
StmtResult FinishCXXForRangeStmt(Stmt *ForRange, Stmt *Body)
FinishCXXForRangeStmt - Attach the body to a C++0x for-range statement.
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
const Stmt * stripLabelLikeStatements() const
Strip off all label-like statements.
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
static std::tuple< bool, const Attr *, const Attr * > determineLikelihoodConflict(const Stmt *Then, const Stmt *Else)
static const Attr * getLikelihoodAttr(const Stmt *S)
SourceLocation getBeginLoc() const LLVM_READONLY
SwitchStmt - This represents a 'switch' stmt.
static SwitchStmt * Create(const ASTContext &Ctx, Stmt *Init, VarDecl *Var, Expr *Cond, SourceLocation LParenLoc, SourceLocation RParenLoc)
Create a switch statement.
SwitchCase * getSwitchCaseList()
DeclStmt * getConditionVariableDeclStmt()
If this SwitchStmt has a condition variable, return the faux DeclStmt associated with the creation of...
void setAllEnumCasesCovered()
Set a flag in the SwitchStmt indicating that if the 'switch (X)' is a switch over an enum value then ...
Represents the declaration of a struct/union/class/enum.
void startDefinition()
Starts the definition of this tag declaration.
TemplateSpecCandidateSet - A set of generalized overload candidates, used in template specializations...
void NoteCandidates(Sema &S, SourceLocation Loc)
NoteCandidates - When no template specialization match is found, prints diagnostic messages containin...
Base wrapper for a particular "section" of type source info.
QualType getType() const
Get the type for which this source info wrapper provides information.
T castAs() const
Convert to the specified TypeLoc type, asserting that this TypeLoc is of the desired type.
T getAsAdjusted() const
Convert to the specified TypeLoc type, returning a null TypeLoc if this TypeLoc is not of the desired...
A container of type source information.
TypeLoc getTypeLoc() const
Return the TypeLoc wrapper for the type source info.
QualType getType() const
Return the type wrapped by this type source info.
The base class of the type hierarchy.
bool isSignedIntegerOrEnumerationType() const
Determines whether this is an integer type that is signed or an enumeration types whose underlying ty...
bool isRValueReferenceType() const
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isPointerType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs<specific type>.
bool isReferenceType() const
bool isEnumeralType() const
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isIntegralOrEnumerationType() const
Determine whether this type is an integral or enumeration type.
AutoType * getContainedAutoType() const
Get the AutoType whose type will be deduced for a variable with an initializer of this type.
bool isSpecificBuiltinType(unsigned K) const
Test for a particular builtin type.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool containsErrors() const
Whether this type is an error type.
EnumDecl * castAsEnumDecl() const
const ArrayType * getAsArrayTypeUnsafe() const
A variant of getAs<> for array types which silently discards qualifiers from the outermost type.
bool isUndeducedType() const
Determine whether this type is an undeduced type, meaning that it somehow involves a C++11 'auto' typ...
bool isObjectType() const
Determine whether this type is an object type.
bool isIncompleteType(NamedDecl **Def=nullptr) const
Types are partitioned into 3 broad categories (C99 6.2.5p1): object types, function types,...
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
TypeClass getTypeClass() const
bool isCanonicalUnqualified() const
Determines if this type would be canonical if it had no further qualification.
const T * getAs() const
Member-template getAs<specific type>'.
bool isRecordType() const
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Expr * getSubExpr() const
Represents a C++ unqualified-id that has been parsed.
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
void setType(QualType newType)
Represents a variable declaration or definition.
static VarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S)
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool hasGlobalStorage() const
Returns true for all variables that do not have local storage.
bool isExceptionVariable() const
Determine whether this variable is the exception variable in a C++ catch statememt or an Objective-C ...
const Expr * getInit() const
bool hasLocalStorage() const
Returns true if a variable with function scope is a non-static local variable.
bool isLocalVarDecl() const
Returns true for local variable declarations other than parameters.
bool hasDependentAlignment() const
Determines if this variable's alignment is dependent.
Represents a C array with a specified size that is not an integer-constant-expression.
static WhileStmt * Create(const ASTContext &Ctx, VarDecl *Var, Expr *Cond, Stmt *Body, SourceLocation WL, SourceLocation LParenLoc, SourceLocation RParenLoc)
Create a while statement.
ValueDecl * getVariable() const
bool isVariableCapture() const
SourceLocation getLocation() const
Retrieve the location at which this variable was captured.
bool isVLATypeCapture() const
bool isThisCapture() const
bool isReferenceCapture() const
Retains information about a captured region.
unsigned short OpenMPLevel
unsigned short CapRegionKind
The kind of captured region.
RecordDecl * TheRecordDecl
The captured record type.
CapturedDecl * TheCapturedDecl
The CapturedDecl for this statement.
QualType ReturnType
ReturnType - The target type of return statements in this context, or null if unknown.
SmallVector< Capture, 4 > Captures
Captures - The captures.
bool HasImplicitReturnType
Contains information about the compound statement currently being parsed.
FPOptions InitialFPFeatures
FP options at the beginning of the compound statement, prior to any pragma.
void setHasEmptyLoopBodies()
Retains information about a function, method, or block that is currently being parsed.
SourceLocation FirstCXXOrObjCTryLoc
First C++ 'try' or ObjC @try statement in the current function.
SourceLocation FirstCoroutineStmtLoc
First coroutine statement in the current function.
enum clang::sema::FunctionScopeInfo::@340304006310276167163023075110222134352007243353 FirstTryType
StringRef getFirstCoroutineStmtKeyword() const
SourceLocation FirstReturnLoc
First 'return' statement in the current function.
SourceLocation FirstSEHTryLoc
First SEH '__try' statement in the current function.
void setHasCXXTry(SourceLocation TryLoc)
SmallVector< CompoundScopeInfo, 4 > CompoundScopes
The stack of currently active compound statement scopes in the function.
void setHasSEHTry(SourceLocation TryLoc)
SmallVector< SwitchInfo, 8 > SwitchStack
SwitchStack - This is the current set of active switch statements in the block.
CXXMethodDecl * CallOperator
The lambda's compiler-generated operator().
Provides information about an attempted template argument deduction, whose success or failure was des...
TemplateArgument SecondArg
The second template argument to which the template argument deduction failure refers.
TemplateArgument FirstArg
The first template argument to which the template argument deduction failure refers.
Defines the clang::TargetInfo interface.
const internal::VariadicAllOfMatcher< Type > type
Matches Types in the clang AST.
const internal::VariadicAllOfMatcher< Decl > decl
Matches declarations.
bool This(InterpState &S, CodePtr OpPC)
bool Cast(InterpState &S, CodePtr OpPC)
void checkExprLifetimeMustTailArg(Sema &SemaRef, const InitializedEntity &Entity, Expr *Init)
Check that the lifetime of the given expr (and its subobjects) is sufficient, assuming that it is pas...
Top level wrappers for InstallAPI frontend operations.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isa(CodeGen::Address addr)
Expr * IgnoreElidableImplicitConstructorSingleStep(Expr *E)
if(T->getSizeExpr()) TRY_TO(TraverseStmt(const_cast< Expr * >(T -> getSizeExpr())))
@ OR_Deleted
Succeeded, but refers to a deleted function.
@ OR_Success
Overload resolution succeeded.
bool isReservedInAllContexts(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved in all contexts.
IfStatementKind
In an if statement, this denotes whether the statement is a constexpr or consteval if statement.
Expr * IgnoreExprNodes(Expr *E, FnTys &&... Fns)
Given an expression E and functions Fn_1,...,Fn_n : Expr * -> Expr *, Recursively apply each of the f...
@ RQ_None
No ref-qualifier was provided.
@ OCD_AllCandidates
Requests that all candidates be shown.
LambdaCaptureKind
The different capture forms in a lambda introducer.
@ LCK_ByRef
Capturing by reference.
@ Seq
'seq' clause, allowed on 'loop' and 'routine' directives.
bool operator==(const CallGraphNode::CallRecord &LHS, const CallGraphNode::CallRecord &RHS)
SmallVector< Attr *, 4 > AttrVec
AttrVec - A vector of Attr, which is how they are stored on the AST.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
CapturedRegionKind
The different kinds of captured statement.
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
const FunctionProtoType * T
AssignConvertType
AssignConvertType - All of the 'assignment' semantic checks return this enum to indicate whether the ...
bool hasArmZT0State(const FunctionDecl *FD)
Returns whether the given FunctionDecl has Arm ZT0 state.
@ Struct
The "struct" keyword.
@ Relational
This is an <, <=, >, or >= that should be implemented as a rewrite in terms of a <=> comparison.
@ ThreeWay
This is an operator<=> that should be implemented as a series of subobject comparisons.
bool isLambdaConversionOperator(CXXConversionDecl *C)
@ Deduced
The normal deduced case.
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
@ VK_XValue
An x-value expression is a reference to an object with independent storage but which can be "moved",...
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
Expr * IgnoreParensSingleStep(Expr *E)
Expr * IgnoreImplicitAsWrittenSingleStep(Expr *E)
DynamicRecursiveASTVisitorBase< false > DynamicRecursiveASTVisitor
TemplateDeductionResult
Describes the result of template argument deduction.
@ Success
Template argument deduction was successful.
@ Inconsistent
Template argument deduction produced inconsistent deduced values for the given template parameter.
@ AlreadyDiagnosed
Some error which was already diagnosed.
U cast(CodeGen::Address addr)
@ CaseValue
Expression in a case label.
bool IsArmStreamingFunction(const FunctionDecl *FD, bool IncludeLocallyStreaming)
Returns whether the given FunctionDecl has an __arm[_locally]_streaming attribute.
ActionResult< Expr * > ExprResult
@ CapturedContext
Parameter for captured context.
ActionResult< Stmt * > StmtResult
bool hasArmZAState(const FunctionDecl *FD)
Returns whether the given FunctionDecl has Arm ZA state.
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
EvalResult is a struct with detailed info about an evaluated expression.
Holds the 'begin' and 'end' variables of a range-based for loop or expansion statement; begin-expr an...
@ MoveEligibleAndCopyElidable
bool isMoveEligible() const
bool isCopyElidable() const
const VarDecl * Candidate
A SwitchStmt, along with a flag indicating if its list of case statements is incomplete (because we d...
static unsigned getHashValue(const CatchHandlerType &Base)
static bool isEqual(const CatchHandlerType &LHS, const CatchHandlerType &RHS)