clang: lib/Sema/SemaExprCXX.cpp Source File (original) (raw)
1
2
3
4
5
6
7
8
9
10
11
12
13
48#include "llvm/ADT/APInt.h"
49#include "llvm/ADT/STLExtras.h"
50#include "llvm/ADT/StringExtras.h"
51#include "llvm/Support/ErrorHandling.h"
52#include "llvm/Support/TypeSize.h"
53#include
54using namespace clang;
55using namespace sema;
56
62 if ([[maybe_unused]] const auto *DNT = dyn_cast(Type))
63 assert(DNT->getIdentifier() == &Name && "not a constructor name");
64
65
66
68 Context.getTrivialTypeSourceInfo(Type, NameLoc));
69}
70
75 assert(CurClass && &II == CurClass->getIdentifier() &&
76 "not a constructor name");
77
78
79
80
85 }
86
89
90
91
92
93
94
95
98 auto *RD = dyn_cast(ND);
99 if (RD && RD->isInjectedClassName()) {
100 InjectedClassName = RD;
101 break;
102 }
103 }
104 if (!InjectedClassName) {
106
107
109 diag::err_incomplete_nested_name_spec) << CurClass << SS.getRange();
110 }
112 }
113
115 InjectedClassName, false);
117}
118
122 bool EnteringContext) {
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
153 return nullptr;
154
155
156 bool Failed = false;
157
160
161
162
163
166
168 auto IsAcceptableResult = [&](NamedDecl *D) -> bool {
169 auto *Type = dyn_cast(D->getUnderlyingDecl());
171 return false;
172
174 return true;
175
177 return Context.hasSameUnqualifiedType(T, SearchType);
178 };
179
180 unsigned NumAcceptableResults = 0;
182 if (IsAcceptableResult(D))
183 ++NumAcceptableResults;
184
185
186
187
188 if (auto *RD = dyn_cast(D))
189 if (RD->isInjectedClassName())
191
192 if (FoundDeclSet.insert(D).second)
193 FoundDecls.push_back(D);
194 }
195
196
197
198
199
200
201 if (Found.isAmbiguous() && NumAcceptableResults == 1) {
202 Diag(NameLoc, diag::ext_dtor_name_ambiguous);
209 std::nullopt, TD);
210 else
211 Diag(D->getLocation(), diag::note_destructor_nontype_here);
212
213 if (!IsAcceptableResult(D))
215 }
217 }
218
219 if (Found.isAmbiguous())
220 Failed = true;
221
223 if (IsAcceptableResult(Type)) {
225 std::nullopt, Type);
228 Context.getTrivialTypeSourceInfo(T, NameLoc));
229 }
230 }
231
232 return nullptr;
233 };
234
235 bool IsDependent = false;
236
237 auto LookupInObjectType = [&]() -> ParsedType {
238 if (Failed || SearchType.isNull())
239 return nullptr;
240
242
245 if (!LookupCtx)
246 return nullptr;
248 return CheckLookupResult(Found);
249 };
250
252 if (Failed)
253 return nullptr;
254
257 if (!LookupCtx)
258 return nullptr;
259
262 Failed = true;
263 return nullptr;
264 }
266 return CheckLookupResult(Found);
267 };
268
269 auto LookupInScope = [&]() -> ParsedType {
270 if (Failed || !S)
271 return nullptr;
272
275 return CheckLookupResult(Found);
276 };
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
315 if (!NNS)
318 return TL.getPrefix();
320 }();
321
322 if (Prefix) {
323
324
325
326
327
329 PrefixSS.Adopt(Prefix);
330 if (ParsedType T = LookupInNestedNameSpec(PrefixSS))
331 return T;
332 } else {
333
334
335
336
337
338
340 return T;
342 return T;
343 }
344
345 if (Failed)
346 return nullptr;
347
348 if (IsDependent) {
349
350
351
356 true);
357 if (T.isNull())
360 }
361
362
363
364 unsigned NumNonExtensionDecls = FoundDecls.size();
365
366 if (SS.isSet()) {
367
368
369
370
371
372 if (ParsedType T = LookupInNestedNameSpec(SS)) {
373 Diag(SS.getEndLoc(), diag::ext_dtor_named_in_wrong_scope)
376 ("::" + II.getName()).str());
377 return T;
378 }
379
380
381
382
383
384
385
386 if (Prefix) {
388 Diag(SS.getEndLoc(), diag::ext_qualified_dtor_named_in_lexical_scope)
390 Diag(FoundDecls.back()->getLocation(), diag::note_destructor_type_here)
392 return T;
393 }
394 }
395 }
396
397
398
399
400
401 FoundDecls.resize(NumNonExtensionDecls);
402
403
407 });
408
409
410 auto MakeFixItHint = [&]{
412
413 if (!SearchType.isNull())
415 else if (S)
416 Destroyed = dyn_cast_or_null(S->getEntity());
417 if (Destroyed)
421 };
422
423 if (FoundDecls.empty()) {
424
425 Diag(NameLoc, diag::err_undeclared_destructor_name)
426 << &II << MakeFixItHint();
427 } else if (!SearchType.isNull() && FoundDecls.size() == 1) {
428 if (auto *TD = dyn_cast(FoundDecls[0]->getUnderlyingDecl())) {
429 assert(!SearchType.isNull() &&
430 "should only reject a type result if we have a search type");
431 Diag(NameLoc, diag::err_destructor_expr_type_mismatch)
433 std::nullopt, TD)
434 << SearchType << MakeFixItHint();
435 } else {
436 Diag(NameLoc, diag::err_destructor_expr_nontype)
437 << &II << MakeFixItHint();
438 }
439 } else {
440 Diag(NameLoc, SearchType.isNull() ? diag::err_destructor_name_nontype
441 : diag::err_destructor_expr_mismatch)
442 << &II << SearchType << MakeFixItHint();
443 }
444
445 for (NamedDecl *FoundD : FoundDecls) {
446 if (auto *TD = dyn_cast(FoundD->getUnderlyingDecl()))
447 Diag(FoundD->getLocation(), diag::note_destructor_type_here)
449 std::nullopt, TD);
450 else
451 Diag(FoundD->getLocation(), diag::note_destructor_nontype_here)
452 << FoundD;
453 }
454
455 return nullptr;
456}
457
461 return nullptr;
462
465 return nullptr;
466 }
467
469 "unexpected type in getDestructorType");
471
472
473
476 .hasSameUnqualifiedType(T, SearchType)) {
478 << T << SearchType;
479 return nullptr;
480 }
481
483}
484
488 if (!IsUDSuffix) {
489
490
491
492
496
499 (StringRef("operator\"\"") + II->getName()).str());
500
501
502
503
504
505
508 Diag(Loc, diag::warn_deprecated_literal_operator_id) << II << Hint;
509
511 Diag(Loc, diag::warn_reserved_extern_symbol)
512 << II << static_cast(Status) << Hint;
513 }
514
517
518
519
520
521 Diag(Name.getBeginLoc(), diag::err_literal_operator_id_outside_namespace)
523 return true;
524
529 return false;
530 }
531
532 llvm_unreachable("unknown nested name specifier kind");
533}
534
539
540
541
542
543
546 = Context.getUnqualifiedArrayType(Operand->getType().getNonReferenceType(),
547 Quals);
548 if (T->isRecordType() &&
551
552 if (T->isVariablyModifiedType())
553 return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid) << T);
554
557
560}
561
566 bool WasEvaluated = false;
571 E = result.get();
572 }
573
575 if (auto *RecordD = T->getAsCXXRecordDecl()) {
576
577
578
581
582
583
584
585
586 if (RecordD->isPolymorphic() && E->isGLValue()) {
588
589
591 if (Result.isInvalid())
594 }
595
596
598 WasEvaluated = true;
599 }
600 }
601
603 if (Result.isInvalid())
606
607
608
609
610
611
613 QualType UnqualT = Context.getUnqualifiedArrayType(T, Quals);
614 if (.hasSameType(T, UnqualT)) {
615 T = UnqualT;
617 }
618 }
619
621 return ExprError(Diag(TypeidLoc, diag::err_variably_modified_typeid)
625
626
628 ? diag::warn_side_effects_typeid
629 : diag::warn_side_effects_unevaluated_context);
630 }
631
634}
635
636
639 bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
640
642 return ExprError(Diag(OpLoc, diag::err_openclcxx_not_supported)
643 << "typeid");
644 }
645
646
648 return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
649
651 IdentifierInfo *TypeInfoII = &PP.getIdentifierTable().get("type_info");
655
656
660 }
662 return ExprError(Diag(OpLoc, diag::err_need_header_before_typeid));
663 }
664
666 return ExprError(Diag(OpLoc, diag::err_no_typeid_with_fno_rtti));
667 }
668
670
671 if (isType) {
672
675 &TInfo);
676 if (T.isNull())
678
679 if (!TInfo)
680 TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc);
681
682 return BuildCXXTypeId(TypeInfoType, OpLoc, TInfo, RParenLoc);
683 }
684
685
688
690 if (auto *CTE = dyn_cast(Result.get()))
691 if (CTE->isPotentiallyEvaluated() && !CTE->isMostDerived(Context))
692 Diag(OpLoc, diag::warn_no_typeid_with_rtti_disabled)
696}
697
698
699
700static void
703
709
711 if (!TD)
712 return;
713
714 if (const auto *Uuid = TD->getMostRecentDecl()->getAttr()) {
715 UuidAttrs.insert(Uuid);
716 return;
717 }
718
719
720 if (const auto *CTSD = dyn_cast(TD)) {
723 const UuidAttr *UuidForTA = nullptr;
727 getUuidAttrOfType(SemaRef, TA.getAsDecl()->getType(), UuidAttrs);
728
729 if (UuidForTA)
730 UuidAttrs.insert(UuidForTA);
731 }
732 }
733}
734
740 if (!Operand->getType()->isDependentType()) {
743 if (UuidAttrs.empty())
744 return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
745 if (UuidAttrs.size() > 1)
746 return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids));
747 Guid = UuidAttrs.back()->getGuidDecl();
748 }
749
752}
753
759
761 } else {
764 if (UuidAttrs.empty())
765 return ExprError(Diag(TypeidLoc, diag::err_uuidof_without_guid));
766 if (UuidAttrs.size() > 1)
767 return ExprError(Diag(TypeidLoc, diag::err_uuidof_with_multiple_guids));
768 Guid = UuidAttrs.back()->getGuidDecl();
769 }
770 }
771
774}
775
776
779 bool isType, void *TyOrExpr, SourceLocation RParenLoc) {
782
783 if (isType) {
784
787 &TInfo);
788 if (T.isNull())
790
791 if (!TInfo)
792 TInfo = Context.getTrivialTypeSourceInfo(T, OpLoc);
793
794 return BuildCXXUuidof(GuidType, OpLoc, TInfo, RParenLoc);
795 }
796
797
799}
800
803 assert((Kind == tok::kw_true || Kind == tok::kw_false) &&
804 "Unknown C++ Boolean value!");
807}
808
813
816 bool IsThrownVarInScope = false;
817 if (Ex) {
818
819
820
821
822
823
824
825
826
827
828
829 if (const auto *DRE = dyn_cast(Ex->IgnoreParens()))
830 if (const auto *Var = dyn_cast(DRE->getDecl());
831 Var && Var->hasLocalStorage() &&
832 !Var->getType().isVolatileQualified()) {
835 IsThrownVarInScope = true;
836 break;
837 }
838
839
843 break;
844 }
845 }
846 }
847
848 return BuildCXXThrow(OpLoc, Ex, IsThrownVarInScope);
849}
850
852 bool IsThrownVarInScope) {
853 const llvm::Triple &T = Context.getTargetInfo().getTriple();
854 const bool IsOpenMPGPUTarget =
855 getLangOpts().OpenMPIsTargetDevice && T.isGPU();
856
858
859
860 if (IsOpenMPGPUTarget)
861 targetDiag(OpLoc, diag::warn_throw_not_valid_on_target) << T.str();
862
863
867
869 Diag(OpLoc, diag::err_omp_simd_region_cannot_use_stmt) << "throw";
870
871
874 Diag(OpLoc, diag::err_acc_branch_in_out_compute_construct)
875 << 2 << 0;
876
878
879
880
881
882
883
884
885
886
887
888
889
890
891
892
895
899
905 Ex = Res.get();
906 }
907
908
909 if (Ex && Context.getTargetInfo().getTriple().isPPC64())
911
914}
915
916static void
918 llvm::DenseMap<CXXRecordDecl *, unsigned> &SubobjectsSeen,
919 llvm::SmallPtrSetImpl<CXXRecordDecl *> &VBases,
920 llvm::SetVector<CXXRecordDecl *> &PublicSubobjectsSeen,
921 bool ParentIsPublic) {
923 CXXRecordDecl *BaseDecl = BS.getType()->getAsCXXRecordDecl();
924 bool NewSubobject;
925
926
927 if (BS.isVirtual())
928 NewSubobject = VBases.insert(BaseDecl).second;
929 else
930 NewSubobject = true;
931
932 if (NewSubobject)
933 ++SubobjectsSeen[BaseDecl];
934
935
936 bool PublicPath = ParentIsPublic && BS.getAccessSpecifier() == AS_public;
937 if (PublicPath)
938 PublicSubobjectsSeen.insert(BaseDecl);
939
940
941 collectPublicBases(BaseDecl, SubobjectsSeen, VBases, PublicSubobjectsSeen,
942 PublicPath);
943 }
944}
945
948 llvm::DenseMap<CXXRecordDecl *, unsigned> SubobjectsSeen;
950 llvm::SetVector<CXXRecordDecl *> PublicSubobjectsSeen;
951 SubobjectsSeen[RD] = 1;
952 PublicSubobjectsSeen.insert(RD);
954 true);
955
956 for (CXXRecordDecl *PublicSubobject : PublicSubobjectsSeen) {
957
958 if (SubobjectsSeen[PublicSubobject] > 1)
959 continue;
960
961 Objects.push_back(PublicSubobject);
962 }
963}
964
967
968
969 QualType Ty = ExceptionObjectTy;
970 bool isPointer = false;
973 isPointer = true;
974 }
975
976
978 Diag(ThrowLoc, diag::err_wasm_reftype_tc) << 0 << E->getSourceRange();
979 return true;
980 }
981
982
984 Diag(ThrowLoc, diag::err_wasm_table_art) << 2 << E->getSourceRange();
985 return true;
986 }
987
988 if (!isPointer || !Ty->isVoidType()) {
990 isPointer ? diag::err_throw_incomplete_ptr
991 : diag::err_throw_incomplete,
993 return true;
994
996 Diag(ThrowLoc, diag::err_throw_sizeless) << Ty << E->getSourceRange();
997 return true;
998 }
999
1001 diag::err_throw_abstract_type, E))
1002 return true;
1003 }
1004
1005
1007 if (!RD)
1008 return false;
1009
1010
1011
1013
1014
1015 if (isPointer)
1016 return false;
1017
1018
1023 PDiag(diag::err_access_dtor_exception) << Ty);
1025 return true;
1026 }
1027 }
1028
1029
1030
1031
1032 if (Context.getTargetInfo().getCXXABI().isMicrosoft()) {
1033
1034
1035
1038
1039 for (CXXRecordDecl *Subobject : UnambiguousPublicSubobjects) {
1040
1041
1042
1043
1046 continue;
1047
1048
1050
1051
1052
1054 continue;
1055
1056
1057
1058
1059
1060
1061
1062 Context.addCopyConstructorForExceptionObject(Subobject, CD);
1063
1064
1065
1066 for (unsigned I = 1, E = CD->getNumParams(); I != E; ++I) {
1068 return true;
1069 }
1070 }
1071 }
1072
1073
1074
1075
1076
1077 if (Context.getTargetInfo().getCXXABI().isItaniumFamily()) {
1080 if (ExnObjAlign < TypeAlign) {
1081 Diag(ThrowLoc, diag::warn_throw_underaligned_obj);
1082 Diag(ThrowLoc, diag::note_throw_underaligned_obj)
1085 }
1086 }
1087 if (!isPointer && getLangOpts().AssumeNothrowExceptionDtor) {
1089 auto Ty = Dtor->getType();
1092 !FT->isNothrow())
1093 Diag(ThrowLoc, diag::err_throw_object_throwing_dtor) << RD;
1094 }
1095 }
1096 }
1097
1098 return false;
1099}
1100
1104
1108
1109
1110
1111
1112
1113
1114
1115
1116
1117
1118
1119
1120
1121
1122
1123
1124
1125
1126
1127
1128
1129
1130
1131
1132
1133
1134
1135
1136
1137
1138
1139
1140
1141
1142
1143
1144
1145 for (int I = FunctionScopes.size();
1151
1153 continue;
1154
1156
1157 if (C.isCopyCapture()) {
1161 }
1162 }
1163
1164
1165
1166
1169 "While computing 'this' capture-type for a generic lambda, when we "
1170 "run out of enclosing LSI's, yet the enclosing DC is a "
1171 "lambda-call-operator we must be (i.e. Current LSI) in a generic "
1172 "lambda call oeprator");
1174
1175 auto IsThisCaptured =
1176 [](CXXRecordDecl *Closure, bool &IsByCopy, bool &IsConst) {
1177 IsConst = false;
1178 IsByCopy = false;
1179 for (auto &&C : Closure->captures()) {
1180 if (C.capturesThis()) {
1182 IsByCopy = true;
1184 IsConst = true;
1185 return true;
1186 }
1187 }
1188 return false;
1189 };
1190
1191 bool IsByCopyCapture = false;
1192 bool IsConstCapture = false;
1194 while (Closure &&
1195 IsThisCaptured(Closure, IsByCopyCapture, IsConstCapture)) {
1196 if (IsByCopyCapture) {
1197 if (IsConstCapture)
1200 }
1203 : nullptr;
1204 }
1205 }
1206 return ThisTy;
1207}
1208
1212
1213 if (CXXMethodDecl *method = dyn_cast(DC)) {
1214 if (method && method->isImplicitObjectMemberFunction())
1215 ThisTy = method->getThisType().getNonReferenceType();
1216 }
1217
1220
1221
1222
1223
1225
1226
1227 ThisTy = Context.getPointerType(ClassTy);
1228 }
1229
1230
1231
1232
1236 return ThisTy;
1237}
1238
1240 Decl *ContextDecl,
1242 bool Enabled)
1244{
1245 if (!Enabled || !ContextDecl)
1246 return;
1247
1251 else
1253
1254
1256 return;
1257
1259 T = S.getASTContext().getQualifiedType(T, CXXThisTypeQuals);
1260
1261 S.CXXThisTypeOverride =
1262 S.Context.getLangOpts().HLSL ? T : S.Context.getPointerType(T);
1263
1264 this->Enabled = true;
1265}
1266
1267
1269 if (Enabled) {
1270 S.CXXThisTypeOverride = OldCXXThisTypeOverride;
1271 }
1272}
1273
1277
1280 return;
1281 Sema.Diag(DiagLoc, diag::note_lambda_this_capture_fixit)
1284}
1285
1287 bool BuildAndDiagnose, const unsigned *const FunctionScopeIndexToStopAt,
1288 const bool ByCopy) {
1289
1291 return true;
1292
1293 assert((!ByCopy || Explicit) && "cannot implicitly capture *this by value");
1294
1295 const int MaxFunctionScopesIndex = FunctionScopeIndexToStopAt
1296 ? *FunctionScopeIndexToStopAt
1298
1299
1300
1301
1302
1303
1304
1305
1306
1307
1308
1309
1310
1311
1312
1313
1314
1315
1316
1317
1318
1319
1320
1321
1322 unsigned NumCapturingClosures = 0;
1323 for (int idx = MaxFunctionScopesIndex; idx >= 0; idx--) {
1325 dyn_cast(FunctionScopes[idx])) {
1326 if (CSI->CXXThisCaptureIndex != 0) {
1327
1328 CSI->Captures[CSI->CXXThisCaptureIndex - 1].markUsed(BuildAndDiagnose);
1329 break;
1330 }
1333
1334 if (BuildAndDiagnose) {
1336 Diag(Loc, diag::err_this_capture)
1337 << (Explicit && idx == MaxFunctionScopesIndex);
1340 }
1341 return true;
1342 }
1347 (Explicit && idx == MaxFunctionScopesIndex)) {
1348
1349
1350
1351
1352
1353 NumCapturingClosures++;
1354 continue;
1355 }
1356
1357 if (BuildAndDiagnose) {
1359 Diag(Loc, diag::err_this_capture)
1360 << (Explicit && idx == MaxFunctionScopesIndex);
1361 }
1364 return true;
1365 }
1366 break;
1367 }
1368 if (!BuildAndDiagnose) return false;
1369
1370
1371
1372
1373
1374
1375
1376
1377
1378
1379 assert((!ByCopy ||
1381 "Only a lambda can capture the enclosing object (referred to by "
1382 "*this) by copy");
1384 for (int idx = MaxFunctionScopesIndex; NumCapturingClosures;
1385 --idx, --NumCapturingClosures) {
1387
1388
1389
1391
1392 bool isNested = NumCapturingClosures > 1;
1393 CSI->addThisCapture(isNested, Loc, CaptureType, ByCopy);
1394 }
1395 return false;
1396}
1397
1399
1400
1401
1402
1404
1407
1409}
1410
1412 if (.isNull())
1413 return false;
1414
1415
1416
1417
1418
1419
1420
1421
1422
1423
1424
1426 const auto *Method = dyn_cast(DC);
1427 if (Method && Method->isExplicitObjectMemberFunction()) {
1428 Diag(Loc, diag::err_invalid_this_use) << 1;
1430 Diag(Loc, diag::err_invalid_this_use) << 1;
1431 } else {
1432 Diag(Loc, diag::err_invalid_this_use) << 0;
1433 }
1434 return true;
1435}
1436
1438 bool IsImplicit) {
1441 return This;
1442}
1443
1446 if (This->isTypeDependent())
1447 return;
1448
1449
1450
1451 auto IsDependent = [&]() {
1453 auto *LSI = dyn_castsema::LambdaScopeInfo(Scope);
1454 if (!LSI)
1455 continue;
1456
1457 if (LSI->Lambda && !LSI->Lambda->Encloses(CurContext) &&
1458 LSI->AfterParameterList)
1459 return false;
1460
1461
1462
1463
1464
1465 if (LSI->isCXXThisCaptured()) {
1466 if (!LSI->getCXXThisCapture().isCopyCapture())
1467 continue;
1468
1469 const auto *MD = LSI->CallOperator;
1470 if (MD->getType().isNull())
1471 return false;
1472
1474 return Ty && MD->isExplicitObjectMemberFunction() &&
1476 }
1477 }
1478 return false;
1479 }();
1480
1481 This->setCapturedByCopyInLambdaWithExplicitObjectParameter(IsDependent);
1482}
1483
1485
1486
1488 return false;
1489
1490
1491
1493 return Class && Class->isBeingDefined();
1494}
1495
1501 bool ListInitialization) {
1502 if (!TypeRep)
1504
1507 if (!TInfo)
1509
1511 RParenOrBraceLoc, ListInitialization);
1512 if (Result.isInvalid())
1514 RParenOrBraceLoc, exprs, Ty);
1516}
1517
1523 bool ListInitialization) {
1527
1531 Exprs.size()
1532 ? ListInitialization
1534 TyBeginLoc, LParenOrBraceLoc, RParenOrBraceLoc)
1536 RParenOrBraceLoc)
1538 RParenOrBraceLoc);
1539
1540
1541
1542
1543
1544
1545
1547 if (Deduced && !Deduced->isDeduced() &&
1550 Kind, Exprs);
1554 } else if (Deduced && !Deduced->isDeduced()) {
1556 if (ListInitialization) {
1558 Inits = MultiExprArg(ILE->getInits(), ILE->getNumInits());
1559 }
1560
1561 if (Inits.empty())
1562 return ExprError(Diag(TyBeginLoc, diag::err_auto_expr_init_no_expression)
1563 << Ty << FullRange);
1564 if (Inits.size() > 1) {
1565 Expr *FirstBad = Inits[1];
1567 diag::err_auto_expr_init_multiple_expressions)
1568 << Ty << FullRange);
1569 }
1571 if (Ty->getAs())
1572 Diag(TyBeginLoc, diag::warn_cxx20_compat_auto_expr) << FullRange;
1573 }
1574 Expr *Deduce = Inits[0];
1577 Diag(Deduce->getBeginLoc(), diag::err_auto_expr_init_paren_braces)
1578 << ListInitialization << Ty << FullRange);
1585 return ExprError(Diag(TyBeginLoc, diag::err_auto_expr_deduction_failure)
1586 << Ty << Deduce->getType() << FullRange
1588 if (DeducedType.isNull()) {
1591 }
1592
1593 Ty = DeducedType;
1595 }
1596
1600 RParenOrBraceLoc, ListInitialization);
1601
1602
1603
1604
1605
1606 if (Exprs.size() == 1 && !ListInitialization &&
1608 Expr *Arg = Exprs[0];
1610 RParenOrBraceLoc);
1611 }
1612
1613
1616 if (!ListInitialization)
1617 return ExprError(Diag(TyBeginLoc, diag::err_value_init_for_array_type)
1618 << FullRange);
1619 ElemTy = Context.getBaseElementType(Ty);
1620 }
1621
1622
1623
1624
1625
1627 return ExprError(Diag(TyBeginLoc, diag::err_init_for_function_type)
1628 << Ty << FullRange);
1629
1630
1631
1632
1634 if (Exprs.empty())
1637 if (ListInitialization &&
1642 Exprs[0]->getBeginLoc(), Exprs[0]->getEndLoc());
1643 }
1645 diag::err_invalid_incomplete_type_use,
1646 FullRange))
1648
1649
1650
1653
1654 if (Result.isInvalid())
1656
1658 if (CXXBindTemporaryExpr *BTE = dyn_cast_or_null(Inner))
1659 Inner = BTE->getSubExpr();
1660 if (auto *CE = dyn_cast(Inner);
1661 CE && CE->isImmediateInvocation())
1662 Inner = CE->getSubExpr();
1665
1666
1667
1668
1669
1670
1671
1672
1676 : SourceRange(LParenOrBraceLoc, RParenOrBraceLoc);
1681 }
1682
1684}
1685
1687
1691
1693 return false;
1695
1697 Method->getDeclContext()->lookup(Method->getDeclName());
1698 for (const auto *D : R) {
1699 if (const auto *FD = dyn_cast(D)) {
1701 return false;
1702 }
1703 }
1704
1705 }
1706 }
1707
1709 bool Result = Method->isUsualDeallocationFunction(PreventedBy);
1710
1713
1714
1715
1716 return llvm::none_of(PreventedBy, [&](const FunctionDecl *FD) {
1718 "Only single-operand functions should be in PreventedBy");
1720 });
1721}
1722
1723
1724
1726 if (CXXMethodDecl *Method = dyn_cast(FD))
1728
1730 return false;
1731
1735
1736 unsigned UsualParams = 1;
1737 if (S.getLangOpts().SizedDeallocation && UsualParams < FD->getNumParams() &&
1741 ++UsualParams;
1742
1743 if (S.getLangOpts().AlignedAllocation && UsualParams < FD->getNumParams() &&
1747 ++UsualParams;
1748
1750}
1751
1752namespace {
1753 struct UsualDeallocFnInfo {
1754 UsualDeallocFnInfo()
1757 UsualDeallocFnInfo(Sema &S, DeclAccessPair Found, QualType AllocType,
1758 SourceLocation Loc)
1759 : Found(Found), FD(dyn_cast(Found->getUnderlyingDecl())),
1760 Destroying(false),
1761 IDP({AllocType, TypeAwareAllocationMode::No,
1762 AlignedAllocationMode::No, SizedDeallocationMode::No}),
1764
1765
1766 if (!FD) {
1767 if (AllocType.isNull())
1768 return;
1769 auto *FTD = dyn_cast(Found->getUnderlyingDecl());
1770 if (!FTD)
1771 return;
1772 FunctionDecl *InstantiatedDecl =
1773 S.BuildTypeAwareUsualDelete(FTD, AllocType, Loc);
1774 if (!InstantiatedDecl)
1775 return;
1776 FD = InstantiatedDecl;
1777 }
1778 unsigned NumBaseParams = 1;
1779 if (FD->isTypeAwareOperatorNewOrDelete()) {
1780
1781
1782
1783
1784
1785 if (AllocType.isNull()) {
1786 FD = nullptr;
1787 return;
1788 }
1789 QualType TypeIdentityTag = FD->getParamDecl(0)->getType();
1790 QualType ExpectedTypeIdentityTag =
1791 S.tryBuildStdTypeIdentity(AllocType, Loc);
1792 if (ExpectedTypeIdentityTag.isNull()) {
1793 FD = nullptr;
1794 return;
1795 }
1796 if (!S.Context.hasSameType(TypeIdentityTag, ExpectedTypeIdentityTag)) {
1797 FD = nullptr;
1798 return;
1799 }
1800 IDP.PassTypeIdentity = TypeAwareAllocationMode::Yes;
1801 ++NumBaseParams;
1802 }
1803
1804 if (FD->isDestroyingOperatorDelete()) {
1805 Destroying = true;
1806 ++NumBaseParams;
1807 }
1808
1809 if (NumBaseParams < FD->getNumParams() &&
1810 S.Context.hasSameUnqualifiedType(
1811 FD->getParamDecl(NumBaseParams)->getType(),
1812 S.Context.getSizeType())) {
1813 ++NumBaseParams;
1814 IDP.PassSize = SizedDeallocationMode::Yes;
1815 }
1816
1817 if (NumBaseParams < FD->getNumParams() &&
1818 FD->getParamDecl(NumBaseParams)->getType()->isAlignValT()) {
1819 ++NumBaseParams;
1820 IDP.PassAlignment = AlignedAllocationMode::Yes;
1821 }
1822
1823
1824 if (S.getLangOpts().CUDA)
1825 CUDAPref = S.CUDA().IdentifyPreference(
1826 S.getCurFunctionDecl(true), FD);
1827 }
1828
1829 explicit operator bool() const { return FD; }
1830
1831 int Compare(Sema &S, const UsualDeallocFnInfo &Other,
1832 ImplicitDeallocationParameters TargetIDP) const {
1835
1836
1837
1838
1839 if (Destroying != Other.Destroying)
1840 return Destroying ? 1 : -1;
1841
1842 const ImplicitDeallocationParameters &OtherIDP = Other.IDP;
1843
1845 return IDP.PassTypeIdentity == TargetIDP.PassTypeIdentity ? 1 : -1;
1846
1847
1848
1849
1850
1851 if (IDP.PassAlignment != OtherIDP.PassAlignment)
1852 return IDP.PassAlignment == TargetIDP.PassAlignment ? 1 : -1;
1853
1854 if (IDP.PassSize != OtherIDP.PassSize)
1855 return IDP.PassSize == TargetIDP.PassSize ? 1 : -1;
1856
1858
1859
1860 FunctionTemplateDecl *PrimaryTemplate = FD->getPrimaryTemplate();
1861 FunctionTemplateDecl *OtherPrimaryTemplate =
1862 Other.FD->getPrimaryTemplate();
1863 if ((!PrimaryTemplate) != (!OtherPrimaryTemplate))
1864 return OtherPrimaryTemplate ? 1 : -1;
1865
1866 if (PrimaryTemplate && OtherPrimaryTemplate) {
1867 const auto *DC = dyn_cast(Found->getDeclContext());
1868 const auto *OtherDC =
1869 dyn_cast(Other.Found->getDeclContext());
1870 unsigned ImplicitArgCount = Destroying + IDP.getNumImplicitArgs();
1872 PrimaryTemplate, OtherPrimaryTemplate, SourceLocation(),
1876 false)) {
1877 return Best == PrimaryTemplate ? 1 : -1;
1878 }
1879 }
1880 }
1881
1882
1883 if (CUDAPref > Other.CUDAPref)
1884 return 1;
1885 if (CUDAPref == Other.CUDAPref)
1886 return 0;
1887 return -1;
1888 }
1889
1890 DeclAccessPair Found;
1891 FunctionDecl *FD;
1892 bool Destroying;
1893 ImplicitDeallocationParameters IDP;
1895 };
1896}
1897
1898
1899
1900
1901
1907
1913 QualType SelectedTypeIdentityParameter =
1916 diag::err_incomplete_type))
1917 return true;
1918 }
1919
1920
1924 S.Diag(StartLoc, diag::err_deleted_function_use)
1925 << (Msg != nullptr) << (Msg ? Msg->getString() : StringRef());
1927 }
1928 return true;
1929 }
1933}
1934
1935
1936
1941
1942 UsualDeallocFnInfo Best;
1943 for (auto I = R.begin(), E = R.end(); I != E; ++I) {
1944 UsualDeallocFnInfo Info(S, I.getPair(), IDP.Type, Loc);
1947 continue;
1948
1951 continue;
1952 if (!Best) {
1953 Best = Info;
1954 if (BestFns)
1955 BestFns->push_back(Info);
1956 continue;
1957 }
1958 int ComparisonResult = Best.Compare(S, Info, IDP);
1959 if (ComparisonResult > 0)
1960 continue;
1961
1962
1963
1964 if (BestFns && ComparisonResult < 0)
1965 BestFns->clear();
1966
1967 Best = Info;
1968 if (BestFns)
1969 BestFns->push_back(Info);
1970 }
1971
1972 return Best;
1973}
1974
1975
1976
1977
1978
1982 const auto *record =
1984 if (!record) return false;
1985
1986
1987
1992
1993
1995
1996
1997 if (ops.empty()) return false;
1998
1999
2000
2002
2003
2004
2005
2007 allocType, PassType,
2012}
2013
2019 std::optional<Expr *> ArraySize;
2020
2025 return ExprError(Diag(Chunk.Loc, diag::err_new_array_of_auto)
2028 return ExprError(Diag(Chunk.Loc, diag::err_static_illegal_in_new)
2031 return ExprError(Diag(Chunk.Loc, diag::err_array_new_needs_size)
2033
2036 }
2037
2038
2039 if (ArraySize) {
2042 break;
2043
2045 if (Expr *NumElts = Array.NumElts) {
2046 if (!NumElts->isTypeDependent() && !NumElts->isValueDependent()) {
2047
2048
2050
2051
2052
2054 Array.NumElts =
2058 } else {
2060 NumElts, nullptr, diag::err_new_array_nonconst,
2063 }
2064 if (!Array.NumElts)
2066 }
2067 }
2068 }
2069 }
2070
2075
2078 DirectInitRange = List->getSourceRange();
2079
2081 PlacementLParen, PlacementArgs, PlacementRParen,
2082 TypeIdParens, AllocType, TInfo, ArraySize, DirectInitRange,
2084}
2085
2087 Expr *Init, bool IsCPlusPlus20) {
2089 return true;
2091 return IsCPlusPlus20 || PLE->getNumExprs() == 0;
2093 return true;
2095 return !CCE->isListInitialization() &&
2096 CCE->getConstructor()->isDefaultConstructor();
2099 "Shouldn't create list CXXConstructExprs for arrays.");
2100 return true;
2101 }
2102 return false;
2103}
2104
2105bool
2107 if (().AlignedAllocationUnavailable)
2108 return false;
2110 return false;
2113 AlignmentParam)
2114 return true;
2115 return false;
2116}
2117
2118
2119
2124 StringRef OSName = AvailabilityAttr::getPlatformNameSourceSpelling(
2127
2129 Diag(Loc, diag::err_aligned_allocation_unavailable)
2131 << OSVersion.getAsString() << OSVersion.empty();
2132 Diag(Loc, diag::note_silence_aligned_allocation_unavailable);
2133 }
2134}
2135
2142 std::optional<Expr *> ArraySize,
2146
2148 if (DirectInitRange.isValid()) {
2149 assert(Initializer && "Have parens but no initializer.");
2151 } else if (isa_and_nonnull(Initializer))
2153 else {
2156 "Initializer expression that cannot have been implicitly created.");
2158 }
2159
2163 "paren init for non-call init");
2164 Exprs = MultiExprArg(List->getExprs(), List->getNumExprs());
2165 } else if (auto *List = dyn_cast_or_null(Initializer)) {
2167 "paren init for non-call init");
2168 Exprs = List->getInitExprs();
2169 }
2170
2171
2172
2173
2175 switch (InitStyle) {
2176
2177
2178
2181
2182
2186 DirectInitRange.getEnd());
2191 }
2192 llvm_unreachable("Unknown initialization kind");
2193 }();
2194
2195
2197 if (Deduced && !Deduced->isDeduced() &&
2199 if (ArraySize)
2201 Diag(*ArraySize ? (*ArraySize)->getExprLoc() : TypeRange.getBegin(),
2202 diag::err_deduced_class_template_compound_type)
2203 << 2
2204 << (*ArraySize ? (*ArraySize)->getSourceRange() : TypeRange));
2205
2209 AllocTypeInfo, Entity, Kind, Exprs);
2210 if (AllocType.isNull())
2212 } else if (Deduced && !Deduced->isDeduced()) {
2215 if (Braced) {
2217 Inits = MultiExprArg(ILE->getInits(), ILE->getNumInits());
2218 }
2219
2221 return ExprError(Diag(StartLoc, diag::err_auto_new_requires_ctor_arg)
2222 << AllocType << TypeRange);
2223 if (Inits.size() > 1) {
2224 Expr *FirstBad = Inits[1];
2226 diag::err_auto_new_ctor_multiple_expressions)
2227 << AllocType << TypeRange);
2228 }
2230 Diag(Initializer->getBeginLoc(), diag::ext_auto_new_list_init)
2231 << AllocType << TypeRange;
2232 Expr *Deduce = Inits[0];
2235 Diag(Deduce->getBeginLoc(), diag::err_auto_expr_init_paren_braces)
2236 << Braced << AllocType << TypeRange);
2243 return ExprError(Diag(StartLoc, diag::err_auto_new_deduction_failure)
2244 << AllocType << Deduce->getType() << TypeRange
2246 if (DeducedType.isNull()) {
2249 }
2250 AllocType = DeducedType;
2251 }
2252
2253
2254
2255
2258 = Context.getAsConstantArrayType(AllocType)) {
2261 TypeRange.getEnd());
2262 AllocType = Array->getElementType();
2263 }
2264 }
2265
2268
2271
2272
2276 AllocType = Context.getLifetimeQualifiedType(AllocType,
2278 }
2279
2280 QualType ResultType = Context.getPointerType(AllocType);
2281
2282 if (ArraySize && *ArraySize &&
2283 (*ArraySize)->getType()->isNonOverloadPlaceholderType()) {
2286 ArraySize = result.get();
2287 }
2288
2289
2290
2291
2292
2293
2294
2295 std::optional<uint64_t> KnownArraySize;
2296 if (ArraySize && *ArraySize && !(*ArraySize)->isTypeDependent()) {
2299 assert(Context.getTargetInfo().getIntWidth() && "Builtin type of size 0?");
2300
2303
2304 if (!ConvertedSize.isInvalid() && (*ArraySize)->getType()->isRecordType())
2305
2306 Diag(StartLoc, diag::warn_cxx98_compat_array_size_conversion)
2307 << (*ArraySize)->getType() << 0 << "'size_t'";
2308 } else {
2310 protected:
2311 Expr *ArraySize;
2312
2313 public:
2314 SizeConvertDiagnoser(Expr *ArraySize)
2316 ArraySize(ArraySize) {}
2317
2320 return S.Diag(Loc, diag::err_array_size_not_integral)
2322 }
2323
2326 return S.Diag(Loc, diag::err_array_size_incomplete_type)
2328 }
2329
2332 return S.Diag(Loc, diag::err_array_size_explicit_conversion) << T << ConvTy;
2333 }
2334
2337 return S.Diag(Conv->getLocation(), diag::note_array_size_conversion)
2339 }
2340
2343 return S.Diag(Loc, diag::err_array_size_ambiguous_conversion) << T;
2344 }
2345
2348 return S.Diag(Conv->getLocation(), diag::note_array_size_conversion)
2350 }
2351
2355 return S.Diag(Loc,
2357 ? diag::warn_cxx98_compat_array_size_conversion
2358 : diag::ext_array_size_conversion)
2360 }
2361 } SizeDiagnoser(*ArraySize);
2362
2364 SizeDiagnoser);
2365 }
2368
2369 ArraySize = ConvertedSize.get();
2370 QualType SizeType = (*ArraySize)->getType();
2371
2372 if (!SizeType->isIntegralOrUnscopedEnumerationType())
2374
2375
2376
2377
2378
2379
2380
2381
2382
2383
2384
2385
2386
2387
2388 if (std::optionalllvm::APSInt Value =
2389 (*ArraySize)->getIntegerConstantExpr(Context)) {
2390 if (Value->isSigned() && Value->isNegative()) {
2391 return ExprError(Diag((*ArraySize)->getBeginLoc(),
2392 diag::err_typecheck_negative_array_size)
2393 << (*ArraySize)->getSourceRange());
2394 }
2395
2397 unsigned ActiveSizeBits =
2401 Diag((*ArraySize)->getBeginLoc(), diag::err_array_too_large)
2403 false, false,
2404 true)
2405 << (*ArraySize)->getSourceRange());
2406 }
2407
2408 KnownArraySize = Value->getZExtValue();
2409 } else if (TypeIdParens.isValid()) {
2410
2411 Diag((*ArraySize)->getBeginLoc(), diag::ext_new_paren_array_nonconst)
2412 << (*ArraySize)->getSourceRange()
2415
2417 }
2418
2419
2420
2421 }
2422
2425 unsigned Alignment =
2427 unsigned NewAlignment = Context.getTargetInfo().getNewAlign();
2431 Alignment > NewAlignment)};
2432
2435
2438 SourceRange AllocationParameterRange = Range;
2439 if (PlacementLParen.isValid() && PlacementRParen.isValid())
2440 AllocationParameterRange = SourceRange(PlacementLParen, PlacementRParen);
2444 AllocType, ArraySize.has_value(), IAP,
2445 PlacementArgs, OperatorNew, OperatorDelete))
2447
2448
2449
2450 bool UsualArrayDeleteWantsSize = false;
2454
2456 if (OperatorNew) {
2457 auto *Proto = OperatorNew->getType()->castAs<FunctionProtoType>();
2461
2462
2463
2464
2465
2466 unsigned NumImplicitArgs = 1;
2468 assert(OperatorNew->isTypeAwareOperatorNewOrDelete());
2469 NumImplicitArgs++;
2470 }
2472 NumImplicitArgs++;
2474 Proto, NumImplicitArgs, PlacementArgs,
2475 AllPlaceArgs, CallType))
2477
2478 if (!AllPlaceArgs.empty())
2479 PlacementArgs = AllPlaceArgs;
2480
2481
2482
2483
2484
2485
2487 unsigned SizeTyWidth = Context.getTypeSize(SizeTy);
2488
2489 llvm::APInt SingleEltSize(
2490 SizeTyWidth, Context.getTypeSizeInChars(AllocType).getQuantity());
2491
2492
2493 std::optionalllvm::APInt AllocationSize;
2495
2496 AllocationSize = SingleEltSize;
2497 } else if (KnownArraySize && !AllocType->isDependentType()) {
2498
2499 bool Overflow;
2500 AllocationSize = llvm::APInt(SizeTyWidth, *KnownArraySize)
2501 .umul_ov(SingleEltSize, Overflow);
2502 (void)Overflow;
2503 assert(
2504 !Overflow &&
2505 "Expected that all the overflows would have been handled already.");
2506 }
2507
2509 Context, AllocationSize.value_or(llvm::APInt::getZero(SizeTyWidth)),
2510 SizeTy, StartLoc);
2511
2512
2515
2516
2517
2518
2524 llvm::APInt(Context.getTypeSize(SizeTy),
2525 Alignment / Context.getCharWidth()),
2526 SizeTy, StartLoc);
2528 CK_IntegralCast, &AlignmentLiteral,
2530
2531
2533 CallArgs.reserve(NumImplicitArgs + PlacementArgs.size());
2534 CallArgs.emplace_back(AllocationSize
2535 ? static_cast<Expr *>(&AllocationSizeLiteral)
2536 : &OpaqueAllocationSize);
2538 CallArgs.emplace_back(&DesiredAlignment);
2539 llvm::append_range(CallArgs, PlacementArgs);
2540
2542
2543 checkCall(OperatorNew, Proto, nullptr, CallArgs,
2544 false, StartLoc, Range, CallType);
2545
2546
2547
2549 (OperatorNew->isImplicit() ||
2550 (OperatorNew->getBeginLoc().isValid() &&
2551 getSourceManager().isInSystemHeader(OperatorNew->getBeginLoc())))) {
2552 if (Alignment > NewAlignment)
2553 Diag(StartLoc, diag::warn_overaligned_type)
2554 << AllocType
2557 }
2558 }
2559
2560
2561
2562
2565 SourceRange InitRange(Exprs.front()->getBeginLoc(),
2566 Exprs.back()->getEndLoc());
2567 Diag(StartLoc, diag::err_new_array_init_args) << InitRange;
2569 }
2570
2571
2572
2575
2577 if (KnownArraySize)
2578 InitType = Context.getConstantArrayType(
2579 AllocType,
2580 llvm::APInt(Context.getTypeSize(Context.getSizeType()),
2581 *KnownArraySize),
2583 else if (ArraySize)
2584 InitType = Context.getIncompleteArrayType(AllocType,
2586 else
2587 InitType = AllocType;
2588
2592 ExprResult FullInit = InitSeq.Perform(*this, Entity, Kind, Exprs);
2595
2596
2597
2598
2600 dyn_cast_or_null(FullInit.get()))
2601 FullInit = Binder->getSubExpr();
2602
2604
2605
2606
2607
2608 if (ArraySize && !*ArraySize) {
2610 if (CAT) {
2611
2612
2615 } else {
2616 Diag(TypeRange.getEnd(), diag::err_new_array_size_unknown_from_init)
2618 }
2619 }
2620 }
2621
2622
2623 if (OperatorNew) {
2627 }
2628 if (OperatorDelete) {
2632 }
2633
2634
2635
2636
2637
2638
2639
2641 dyn_cast_or_null(Initializer);
2642 CCE && ArraySize) {
2643 Context.setClassNeedsVectorDeletingDestructor(
2644 CCE->getConstructor()->getParent());
2645 }
2646
2648 IAP, UsualArrayDeleteWantsSize, PlacementArgs,
2649 TypeIdParens, ArraySize, InitStyle, Initializer,
2650 ResultType, AllocTypeInfo, Range, DirectInitRange);
2651}
2652
2655
2656
2658 return Diag(Loc, diag::err_bad_new_type)
2659 << AllocType << 0 << R;
2661 return Diag(Loc, diag::err_bad_new_type)
2662 << AllocType << 1 << R;
2665 Loc, AllocType, diag::err_new_incomplete_or_sizeless_type, R))
2666 return true;
2668 diag::err_allocation_of_abstract_type))
2669 return true;
2671 return Diag(Loc, diag::err_variably_modified_new_type)
2672 << AllocType;
2675 return Diag(Loc, diag::err_address_space_qualified_new)
2678 else if (getLangOpts().ObjCAutoRefCount) {
2679 if (const ArrayType *AT = Context.getAsArrayType(AllocType)) {
2680 QualType BaseAllocType = Context.getBaseElementType(AT);
2683 return Diag(Loc, diag::err_arc_new_array_without_ownership)
2684 << BaseAllocType;
2685 }
2686 }
2687
2688 return false;
2689}
2690
2697 unsigned NonTypeArgumentOffset = 0;
2699 ++NonTypeArgumentOffset;
2700 }
2701
2705 Alloc != AllocEnd; ++Alloc) {
2706
2707
2711 continue;
2712
2715 nullptr, Args,
2716 Candidates,
2717 false);
2718 continue;
2719 }
2720
2723 false);
2724 }
2725
2726
2730
2734 return true;
2735
2736 Operator = FnDecl;
2737 return false;
2738 }
2739
2741
2742
2743
2744
2747 AlignArg = Args[NonTypeArgumentOffset + 1];
2748 Args.erase(Args.begin() + NonTypeArgumentOffset + 1);
2750 PassAlignment, Operator,
2751 &Candidates, AlignArg, Diagnose);
2752 }
2753
2754
2755
2756
2757
2758
2759
2765
2767 PassAlignment, Operator,
2768 nullptr,
2769 nullptr, Diagnose);
2770 }
2772
2773
2774 Operator = nullptr;
2775 return false;
2776 }
2778
2779
2780
2782 (Args[1]->getType()->isObjectPointerType() ||
2783 Args[1]->getType()->isArrayType())) {
2784 const QualType Arg1Type = Args[1]->getType();
2789 S.Diag(Args[1]->getExprLoc(),
2790 diag::err_placement_new_into_const_qualified_storage)
2791 << Arg1Type << Args[1]->getSourceRange();
2792 return true;
2793 }
2794 S.Diag(R.getNameLoc(), diag::err_need_header_before_placement_new)
2796
2797 return true;
2798 }
2799
2800
2801
2802
2803
2804
2805
2809 if (AlignedCandidates) {
2811 auto AlignArgOffset = NonTypeArgumentOffset + 1;
2812 return C.Function->getNumParams() > AlignArgOffset &&
2813 C.Function->getParamDecl(AlignArgOffset)
2814 ->getType()
2815 ->isAlignValT();
2816 };
2818
2819 AlignedArgs.reserve(Args.size() + NonTypeArgumentOffset + 1);
2820 for (unsigned Idx = 0; Idx < NonTypeArgumentOffset + 1; ++Idx)
2821 AlignedArgs.push_back(Args[Idx]);
2822 AlignedArgs.push_back(AlignArg);
2823 AlignedArgs.append(Args.begin() + NonTypeArgumentOffset + 1,
2824 Args.end());
2827
2830 } else {
2833 }
2834
2835 S.Diag(R.getNameLoc(), diag::err_ovl_no_viable_function_in_call)
2837 if (AlignedCandidates)
2838 AlignedCandidates->NoteCandidates(S, AlignedArgs, AlignedCands, "",
2841 }
2842 return true;
2843
2848 S.PDiag(diag::err_ovl_ambiguous_call)
2851 }
2852 return true;
2853
2857 Candidates, Best->Function, Args);
2858 return true;
2859 }
2860 }
2861 llvm_unreachable("Unreachable, bad result from BestViableFunction");
2862}
2863
2865
2872
2875 while (Filter.hasNext()) {
2876 FunctionDecl *FD = Filter.next()->getUnderlyingDecl()->getAsFunction();
2878 Filter.erase();
2879 }
2880 Filter.done();
2881 }
2882}
2883
2888 Operator = nullptr;
2891
2892
2893
2894
2896 UntypedParameters.reserve(Args.size() - 1);
2897 UntypedParameters.push_back(Args[1]);
2898
2899
2900
2902 UntypedParameters.push_back(Args[2]);
2903 UntypedParameters.append(Args.begin() + 3, Args.end());
2904
2909 AlignedCandidates, AlignArg, Diagnose))
2910 return true;
2911 if (Operator)
2912 return false;
2913
2914
2915
2916
2919 Args = std::move(UntypedParameters);
2920 }
2924 AlignedCandidates, AlignArg, Diagnose);
2925}
2926
2933
2934
2935
2936
2937
2938
2939
2940
2941
2942
2943
2944
2947
2948
2949
2950
2951
2952
2953
2955 IsArray ? OO_Array_New : OO_New);
2956
2957 QualType AllocElemType = Context.getBaseElementType(AllocType);
2958
2959
2960
2961
2962
2963
2964
2965
2968 QualType SpecializedTypeIdentity =
2970 if (!SpecializedTypeIdentity.isNull()) {
2971 TypeIdentity = SpecializedTypeIdentity;
2973 diag::err_incomplete_type))
2974 return true;
2975 } else
2977 }
2979
2982 AllocArgs.push_back(&TypeIdentityParam);
2983
2985 unsigned SizeTyWidth = Context.getTypeSize(SizeTy);
2988 AllocArgs.push_back(&Size);
2989
2993 if (IncludeAlignParam) {
2996 }
2998 if (IncludeAlignParam)
2999 AllocArgs.push_back(&Align);
3000
3001 llvm::append_range(AllocArgs, PlaceArgs);
3002
3003
3004 {
3006
3007
3008
3009
3010
3011
3015
3016
3017
3019 return true;
3020
3021
3022
3023
3024 if (R.empty()) {
3026 return true;
3027
3029 }
3030
3032 if (PlaceArgs.empty()) {
3033 Diag(StartLoc, diag::err_openclcxx_not_supported) << "default new";
3034 } else {
3035 Diag(StartLoc, diag::err_openclcxx_placement_new);
3036 }
3037 return true;
3038 }
3039
3040 assert(!R.empty() && "implicitly declared allocation functions not found");
3041 assert(!R.isAmbiguous() && "global allocation functions are ambiguous");
3042
3043
3045
3047 nullptr,
3048 nullptr, Diagnose))
3049 return true;
3050 }
3051
3052
3054 OperatorDelete = nullptr;
3055 return false;
3056 }
3057
3058
3059
3061 OperatorNew->getDeclName().getCXXOverloadedOperator() == OO_Array_New
3062 ? OO_Array_Delete
3063 : OO_Delete);
3064
3065
3066
3067
3068
3069
3070
3071
3072
3073
3079 }
3081 return true;
3082
3083
3084
3085
3086
3087 {
3089 while (Filter.hasNext()) {
3090 auto *FD = dyn_cast(Filter.next()->getUnderlyingDecl());
3091 if (FD && FD->isDestroyingOperatorDelete())
3092 Filter.erase();
3093 }
3094 Filter.done();
3095 }
3096
3097 auto GetRedeclContext = [](Decl *D) {
3098 return D->getDeclContext()->getRedeclContext();
3099 };
3100
3101 DeclContext *OperatorNewContext = GetRedeclContext(OperatorNew);
3102
3103 bool FoundGlobalDelete = FoundDelete.empty();
3104 bool IsClassScopedTypeAwareNew =
3106 OperatorNewContext->isRecord();
3107 auto DiagnoseMissingTypeAwareCleanupOperator = [&](bool IsPlacementOperator) {
3110 Diag(StartLoc, diag::err_mismatching_type_aware_cleanup_deallocator)
3111 << OperatorNew->getDeclName() << IsPlacementOperator << DeleteName;
3112 Diag(OperatorNew->getLocation(), diag::note_type_aware_operator_declared)
3113 << OperatorNew->isTypeAwareOperatorNewOrDelete()
3114 << OperatorNew->getDeclName() << OperatorNewContext;
3115 }
3116 };
3117 if (IsClassScopedTypeAwareNew && FoundDelete.empty()) {
3118 DiagnoseMissingTypeAwareCleanupOperator(false);
3119 return true;
3120 }
3121 if (FoundDelete.empty()) {
3123
3125 return true;
3126
3132 DeleteName);
3133 }
3134
3136
3138
3139
3140
3141
3142
3143
3144
3145
3146
3147
3148
3149
3150
3151
3152
3153 unsigned NonPlacementNewArgCount = 1;
3155 NonPlacementNewArgCount =
3156 1 + 1 + 1;
3157 bool isPlacementNew = !PlaceArgs.empty() ||
3158 OperatorNew->param_size() != NonPlacementNewArgCount ||
3159 OperatorNew->isVariadic();
3160
3161 if (isPlacementNew) {
3162
3163
3164
3165
3166
3167
3168
3169
3170
3171
3172 QualType ExpectedFunctionType;
3173 {
3174 auto *Proto = OperatorNew->getType()->castAs<FunctionProtoType>();
3175
3177 int InitialParamOffset = 0;
3179 ArgTypes.push_back(TypeIdentity);
3180 InitialParamOffset = 1;
3181 }
3182 ArgTypes.push_back(Context.VoidPtrTy);
3183 for (unsigned I = ArgTypes.size() - InitialParamOffset,
3184 N = Proto->getNumParams();
3185 I < N; ++I)
3186 ArgTypes.push_back(Proto->getParamType(I));
3187
3189
3190 EPI.Variadic = Proto->isVariadic();
3191
3192 ExpectedFunctionType
3193 = Context.getFunctionType(Context.VoidTy, ArgTypes, EPI);
3194 }
3195
3197 DEnd = FoundDelete.end();
3198 D != DEnd; ++D) {
3201 dyn_cast((*D)->getUnderlyingDecl())) {
3202
3203
3207 continue;
3208 } else
3210
3212 ExpectedFunctionType,
3213 true),
3214 ExpectedFunctionType))
3215 Matches.push_back(std::make_pair(D.getPair(), Fn));
3216 }
3217
3220 Matches);
3222 DiagnoseMissingTypeAwareCleanupOperator(isPlacementNew);
3223 return true;
3224 }
3225 } else {
3226
3227
3228
3229
3230
3231
3232
3235 AllocElemType, OriginalTypeAwareState,
3240 *this, FoundDelete, IDP, StartLoc, &BestDeallocFns);
3241 if (Selected && BestDeallocFns.empty())
3242 Matches.push_back(std::make_pair(Selected.Found, Selected.FD));
3243 else {
3244
3245
3246 for (auto Fn : BestDeallocFns)
3247 Matches.push_back(std::make_pair(Fn.Found, Fn.FD));
3248 }
3249 }
3250
3251
3252
3253
3254
3255 if (Matches.size() == 1) {
3256 OperatorDelete = Matches[0].second;
3257 DeclContext *OperatorDeleteContext = GetRedeclContext(OperatorDelete);
3258 bool FoundTypeAwareOperator =
3259 OperatorDelete->isTypeAwareOperatorNewOrDelete() ||
3260 OperatorNew->isTypeAwareOperatorNewOrDelete();
3261 if (Diagnose && FoundTypeAwareOperator) {
3262 bool MismatchedTypeAwareness =
3263 OperatorDelete->isTypeAwareOperatorNewOrDelete() !=
3264 OperatorNew->isTypeAwareOperatorNewOrDelete();
3265 bool MismatchedContext = OperatorDeleteContext != OperatorNewContext;
3266 if (MismatchedTypeAwareness || MismatchedContext) {
3267 FunctionDecl *Operators[] = {OperatorDelete, OperatorNew};
3268 bool TypeAwareOperatorIndex =
3270 Diag(StartLoc, diag::err_mismatching_type_aware_cleanup_deallocator)
3271 << Operators[TypeAwareOperatorIndex]->getDeclName()
3272 << isPlacementNew
3273 << Operators[!TypeAwareOperatorIndex]->getDeclName()
3274 << GetRedeclContext(Operators[TypeAwareOperatorIndex]);
3275 Diag(OperatorNew->getLocation(),
3276 diag::note_type_aware_operator_declared)
3277 << OperatorNew->isTypeAwareOperatorNewOrDelete()
3278 << OperatorNew->getDeclName() << OperatorNewContext;
3279 Diag(OperatorDelete->getLocation(),
3280 diag::note_type_aware_operator_declared)
3281 << OperatorDelete->isTypeAwareOperatorNewOrDelete()
3282 << OperatorDelete->getDeclName() << OperatorDeleteContext;
3283 }
3284 }
3285
3286
3287
3288
3289
3290
3291
3294 UsualDeallocFnInfo Info(*this,
3296 AllocElemType, StartLoc);
3297
3298
3299
3300
3302 if (IsSizedDelete && !FoundGlobalDelete) {
3307 *this, FoundDelete, SizeTestingIDP, StartLoc);
3308 if (NonSizedDelete &&
3310 NonSizedDelete.IDP.PassAlignment == Info.IDP.PassAlignment)
3311 IsSizedDelete = false;
3312 }
3313
3317 : SourceRange(PlaceArgs.front()->getBeginLoc(),
3318 PlaceArgs.back()->getEndLoc());
3319 Diag(StartLoc, diag::err_placement_new_non_placement_delete) << R;
3320 if (!OperatorDelete->isImplicit())
3321 Diag(OperatorDelete->getLocation(), diag::note_previous_decl)
3322 << DeleteName;
3323 }
3324 }
3327 Matches[0].second))
3328 return true;
3329
3330 } else if (!Matches.empty()) {
3331
3332
3333
3334 Diag(StartLoc, diag::warn_ambiguous_suitable_delete_function_found)
3335 << DeleteName << AllocElemType;
3336
3337 for (auto &Match : Matches)
3338 Diag(Match.second->getLocation(),
3339 diag::note_member_declared_here) << DeleteName;
3340 }
3341
3342 return false;
3343}
3344
3347 return;
3348
3349
3350
3352 return;
3353
3354
3355
3356
3357
3358
3361
3362
3363
3364
3365
3366
3367
3368
3369
3370
3371
3372
3373
3374
3375
3376
3377
3378
3379
3380
3381
3382
3383
3384
3385
3386
3387
3388
3389
3390
3391
3393
3394
3398 &PP.getIdentifierTable().get("bad_alloc"), nullptr);
3400
3401
3402
3403 if (TheGlobalModuleFragment) {
3407 }
3408 }
3410
3411
3414 &PP.getIdentifierTable().get("align_val_t"), nullptr, true, true, true);
3415
3416
3417
3418 if (TheGlobalModuleFragment) {
3419 AlignValT->setModuleOwnershipKind(
3421 AlignValT->setLocalOwningModule(TheGlobalModuleFragment);
3422 }
3423
3424 AlignValT->setIntegerType(Context.getSizeType());
3425 AlignValT->setPromotionType(Context.getSizeType());
3426 AlignValT->setImplicit(true);
3427
3429 }
3430
3432
3435
3439 Params.push_back(Param);
3440
3441
3442 bool HasSizedVariant = getLangOpts().SizedDeallocation &&
3443 (Kind == OO_Delete || Kind == OO_Array_Delete);
3444 bool HasAlignedVariant = getLangOpts().AlignedAllocation;
3445
3446 int NumSizeVariants = (HasSizedVariant ? 2 : 1);
3447 int NumAlignVariants = (HasAlignedVariant ? 2 : 1);
3448 for (int Sized = 0; Sized < NumSizeVariants; ++Sized) {
3449 if (Sized)
3450 Params.push_back(SizeT);
3451
3452 for (int Aligned = 0; Aligned < NumAlignVariants; ++Aligned) {
3453 if (Aligned)
3455
3457 Context.DeclarationNames.getCXXOperatorName(Kind), Return, Params);
3458
3459 if (Aligned)
3460 Params.pop_back();
3461 }
3462 }
3463 };
3464
3465 DeclareGlobalAllocationFunctions(OO_New, VoidPtr, SizeT);
3466 DeclareGlobalAllocationFunctions(OO_Array_New, VoidPtr, SizeT);
3467 DeclareGlobalAllocationFunctions(OO_Delete, Context.VoidTy, VoidPtr);
3468 DeclareGlobalAllocationFunctions(OO_Array_Delete, Context.VoidTy, VoidPtr);
3469
3471 PopGlobalModuleFragment();
3472}
3473
3474
3475
3480
3481
3484 Alloc != AllocEnd; ++Alloc) {
3485
3486
3488 if (Func->getNumParams() == Params.size()) {
3489 if (std::equal(Func->param_begin(), Func->param_end(), Params.begin(),
3491 return Context.hasSameUnqualifiedType(D->getType(),
3492 RT);
3493 })) {
3494
3495
3496
3497 Func->setVisibleDespiteOwningModule();
3498 return;
3499 }
3500 }
3501 }
3502 }
3503
3505 Context.getTargetInfo().getDefaultCallingConv());
3506
3509 if (HasBadAllocExceptionSpec) {
3512 assert(StdBadAlloc && "Must have std::bad_alloc declared");
3515 }
3518 }
3519 } else {
3522 }
3523
3524 auto CreateAllocationFunctionDecl = [&](Attr *ExtraAttr) {
3525
3526
3527
3528
3529
3530 if (getLangOpts().CUDAIsDevice && ExtraAttr &&
3532 Context.getTargetInfo().getTriple().isSPIRV()) {
3533 if (auto *ATI = Context.getAuxTargetInfo())
3535 else
3537 }
3538 QualType FnType = Context.getFunctionType(Return, Params, EPI);
3542 true);
3543 Alloc->setImplicit();
3544
3545 Alloc->setVisibleDespiteOwningModule();
3546
3547 if (HasBadAllocExceptionSpec && getLangOpts().NewInfallible &&
3549 Alloc->addAttr(
3550 ReturnsNonNullAttr::CreateImplicit(Context, Alloc->getLocation()));
3551
3552
3553
3554
3555
3556
3557
3558
3559
3560
3561
3562 if (TheGlobalModuleFragment) {
3563 Alloc->setModuleOwnershipKind(
3565 Alloc->setLocalOwningModule(TheGlobalModuleFragment);
3566 }
3567
3568 if (LangOpts.hasGlobalAllocationFunctionVisibility())
3569 Alloc->addAttr(VisibilityAttr::CreateImplicit(
3570 Context, LangOpts.hasHiddenGlobalAllocationFunctionVisibility()
3571 ? VisibilityAttr::Hidden
3572 : LangOpts.hasProtectedGlobalAllocationFunctionVisibility()
3573 ? VisibilityAttr::Protected
3574 : VisibilityAttr::Default));
3575
3580 nullptr, SC_None, nullptr));
3581 ParamDecls.back()->setImplicit();
3582 }
3583 Alloc->setParams(ParamDecls);
3584 if (ExtraAttr)
3585 Alloc->addAttr(ExtraAttr);
3587 Context.getTranslationUnitDecl()->addDecl(Alloc);
3588 IdResolver.tryAddTopLevelDecl(Alloc, Name);
3589 };
3590
3592 CreateAllocationFunctionDecl(nullptr);
3593 else {
3594
3595
3596 CreateAllocationFunctionDecl(CUDAHostAttr::CreateImplicit(Context));
3597 CreateAllocationFunctionDecl(CUDADeviceAttr::CreateImplicit(Context));
3598 }
3599}
3600
3606
3610
3611
3612
3613
3614
3617 return nullptr;
3618
3622 return nullptr;
3623
3624 assert(Result.FD && "operator delete missing from global scope?");
3626}
3627
3631
3637
3638 if (!LookForGlobal) {
3640 return nullptr;
3641
3642 if (OperatorDelete)
3643 return OperatorDelete;
3644 }
3645
3646
3647
3652}
3653
3660
3662
3663 if (Found.isAmbiguous()) {
3665 Found.suppressDiagnostics();
3666 return true;
3667 }
3668
3669 Found.suppressDiagnostics();
3670
3674
3675
3676
3677
3680
3681
3682 if (Matches.size() == 1) {
3685 Found.getNamingClass(), Matches[0].Found,
3686 Operator);
3687 }
3688
3689
3690
3691
3692 if (!Matches.empty()) {
3694 Diag(StartLoc, diag::err_ambiguous_suitable_delete_member_function_found)
3695 << Name << RD;
3696 for (auto &Match : Matches)
3697 Diag(Match.FD->getLocation(), diag::note_member_declared_here) << Name;
3698 }
3699 return true;
3700 }
3701
3702
3703
3704 if (.empty()) {
3706 Diag(StartLoc, diag::err_no_suitable_delete_member_function_found)
3707 << Name << RD;
3708
3710 Diag(D->getUnderlyingDecl()->getLocation(),
3711 diag::note_member_declared_here) << Name;
3712 }
3713 return true;
3714 }
3715
3716 Operator = nullptr;
3717 return false;
3718}
3719
3720namespace {
3721
3722
3723class MismatchingNewDeleteDetector {
3724public:
3725 enum MismatchResult {
3726
3727 NoMismatch,
3728
3729 VarInitMismatches,
3730
3731 MemberInitMismatches,
3732
3733
3734 AnalyzeLater
3735 };
3736
3737
3738
3739
3740 explicit MismatchingNewDeleteDetector(bool EndOfTU)
3741 : Field(nullptr), IsArrayForm(false), EndOfTU(EndOfTU),
3742 HasUndefinedConstructors(false) {}
3743
3744
3745
3746
3747
3748
3749
3750
3751
3752
3753
3754 MismatchResult analyzeDeleteExpr(const CXXDeleteExpr *DE);
3755
3756
3757
3758
3759 MismatchResult analyzeField(FieldDecl *Field, bool DeleteWasArrayForm);
3760 FieldDecl *Field;
3761
3762 llvm::SmallVector<const CXXNewExpr *, 4> NewExprs;
3763
3764 bool IsArrayForm;
3765
3766private:
3767 const bool EndOfTU;
3768
3769 bool HasUndefinedConstructors;
3770
3771
3772
3773 const CXXNewExpr *getNewExprFromInitListOrExpr(const Expr *E);
3774
3775
3776
3777
3778
3779
3780
3781 MismatchResult analyzeMemberExpr(const MemberExpr *ME);
3782
3783
3784
3785
3786
3787
3788
3789 bool hasMatchingVarInit(const DeclRefExpr *D);
3790
3791
3792
3793
3794
3795
3796
3797
3798 bool hasMatchingNewInCtor(const CXXConstructorDecl *CD);
3799
3800
3801 bool hasMatchingNewInCtorInit(const CXXCtorInitializer *CI);
3802
3803
3804 MismatchResult analyzeInClassInitializer();
3805};
3806}
3807
3808MismatchingNewDeleteDetector::MismatchResult
3809MismatchingNewDeleteDetector::analyzeDeleteExpr(const CXXDeleteExpr *DE) {
3810 NewExprs.clear();
3811 assert(DE && "Expected delete-expression");
3814 if (const MemberExpr *ME = dyn_cast(E)) {
3815 return analyzeMemberExpr(ME);
3816 } else if (const DeclRefExpr *D = dyn_cast(E)) {
3817 if (!hasMatchingVarInit(D))
3818 return VarInitMismatches;
3819 }
3820 return NoMismatch;
3821}
3822
3823const CXXNewExpr *
3824MismatchingNewDeleteDetector::getNewExprFromInitListOrExpr(const Expr *E) {
3825 assert(E != nullptr && "Expected a valid initializer expression");
3827 if (const InitListExpr *ILE = dyn_cast(E)) {
3828 if (ILE->getNumInits() == 1)
3829 E = dyn_cast(ILE->getInit(0)->IgnoreParenImpCasts());
3830 }
3831
3832 return dyn_cast_or_null(E);
3833}
3834
3835bool MismatchingNewDeleteDetector::hasMatchingNewInCtorInit(
3836 const CXXCtorInitializer *CI) {
3837 const CXXNewExpr *NE = nullptr;
3839 (NE = getNewExprFromInitListOrExpr(CI->getInit()))) {
3840 if (NE->isArray() == IsArrayForm)
3841 return true;
3842 else
3843 NewExprs.push_back(NE);
3844 }
3845 return false;
3846}
3847
3848bool MismatchingNewDeleteDetector::hasMatchingNewInCtor(
3849 const CXXConstructorDecl *CD) {
3851 return false;
3852 const FunctionDecl *Definition = CD;
3854 HasUndefinedConstructors = true;
3855 return EndOfTU;
3856 }
3858 if (hasMatchingNewInCtorInit(CI))
3859 return true;
3860 }
3861 return false;
3862}
3863
3864MismatchingNewDeleteDetector::MismatchResult
3865MismatchingNewDeleteDetector::analyzeInClassInitializer() {
3866 assert(Field != nullptr && "This should be called only for members");
3867 const Expr *InitExpr = Field->getInClassInitializer();
3868 if (!InitExpr)
3869 return EndOfTU ? NoMismatch : AnalyzeLater;
3870 if (const CXXNewExpr *NE = getNewExprFromInitListOrExpr(InitExpr)) {
3871 if (NE->isArray() != IsArrayForm) {
3872 NewExprs.push_back(NE);
3873 return MemberInitMismatches;
3874 }
3875 }
3876 return NoMismatch;
3877}
3878
3879MismatchingNewDeleteDetector::MismatchResult
3880MismatchingNewDeleteDetector::analyzeField(FieldDecl *Field,
3881 bool DeleteWasArrayForm) {
3882 assert(Field != nullptr && "Analysis requires a valid class member.");
3884 IsArrayForm = DeleteWasArrayForm;
3886 for (const auto *CD : RD->ctors()) {
3887 if (hasMatchingNewInCtor(CD))
3888 return NoMismatch;
3889 }
3890 if (HasUndefinedConstructors)
3891 return EndOfTU ? NoMismatch : AnalyzeLater;
3892 if (!NewExprs.empty())
3893 return MemberInitMismatches;
3894 return Field->hasInClassInitializer() ? analyzeInClassInitializer()
3895 : NoMismatch;
3896}
3897
3898MismatchingNewDeleteDetector::MismatchResult
3899MismatchingNewDeleteDetector::analyzeMemberExpr(const MemberExpr *ME) {
3900 assert(ME != nullptr && "Expected a member expression");
3901 if (FieldDecl *F = dyn_cast(ME->getMemberDecl()))
3902 return analyzeField(F, IsArrayForm);
3903 return NoMismatch;
3904}
3905
3906bool MismatchingNewDeleteDetector::hasMatchingVarInit(const DeclRefExpr *D) {
3907 const CXXNewExpr *NE = nullptr;
3908 if (const VarDecl *VD = dyn_cast(D->getDecl())) {
3909 if (VD->hasInit() && (NE = getNewExprFromInitListOrExpr(VD->getInit())) &&
3910 NE->isArray() != IsArrayForm) {
3911 NewExprs.push_back(NE);
3912 }
3913 }
3914 return NewExprs.empty();
3915}
3916
3917static void
3919 const MismatchingNewDeleteDetector &Detector) {
3922 if (!Detector.IsArrayForm)
3924 else {
3930 }
3931 SemaRef.Diag(DeleteLoc, diag::warn_mismatched_delete_new)
3932 << Detector.IsArrayForm << H;
3933
3934 for (const auto *NE : Detector.NewExprs)
3935 SemaRef.Diag(NE->getExprLoc(), diag::note_allocated_here)
3936 << Detector.IsArrayForm;
3937}
3938
3939void Sema::AnalyzeDeleteExprMismatch(const CXXDeleteExpr *DE) {
3940 if (Diags.isIgnored(diag::warn_mismatched_delete_new, SourceLocation()))
3941 return;
3942 MismatchingNewDeleteDetector Detector(false);
3943 switch (Detector.analyzeDeleteExpr(DE)) {
3944 case MismatchingNewDeleteDetector::VarInitMismatches:
3945 case MismatchingNewDeleteDetector::MemberInitMismatches: {
3947 break;
3948 }
3949 case MismatchingNewDeleteDetector::AnalyzeLater: {
3952 break;
3953 }
3954 case MismatchingNewDeleteDetector::NoMismatch:
3955 break;
3956 }
3957}
3958
3959void Sema::AnalyzeDeleteExprMismatch(FieldDecl *Field, SourceLocation DeleteLoc,
3960 bool DeleteWasArrayForm) {
3961 MismatchingNewDeleteDetector Detector(true);
3962 switch (Detector.analyzeField(Field, DeleteWasArrayForm)) {
3963 case MismatchingNewDeleteDetector::VarInitMismatches:
3964 llvm_unreachable("This analysis should have been done for class members.");
3965 case MismatchingNewDeleteDetector::AnalyzeLater:
3966 llvm_unreachable("Analysis cannot be postponed any point beyond end of "
3967 "translation unit.");
3968 case MismatchingNewDeleteDetector::MemberInitMismatches:
3970 break;
3971 case MismatchingNewDeleteDetector::NoMismatch:
3972 break;
3973 }
3974}
3975
3978 bool ArrayForm, Expr *ExE) {
3979
3980
3981
3982
3983
3984
3985
3988 bool ArrayFormAsWritten = ArrayForm;
3989 bool UsualArrayDeleteWantsSize = false;
3990
3992
3996
3998
4000 public:
4002
4004
4005
4007 if (ConvPtrType->getPointeeType()->isIncompleteOrObjectType())
4008 return true;
4009 return false;
4010 }
4011
4014 return S.Diag(Loc, diag::err_delete_operand) << T;
4015 }
4016
4019 return S.Diag(Loc, diag::err_delete_incomplete_class_type) << T;
4020 }
4021
4025 return S.Diag(Loc, diag::err_delete_explicit_conversion) << T << ConvTy;
4026 }
4027
4030 return S.Diag(Conv->getLocation(), diag::note_delete_conversion)
4031 << ConvTy;
4032 }
4033
4036 return S.Diag(Loc, diag::err_ambiguous_delete_operand) << T;
4037 }
4038
4041 return S.Diag(Conv->getLocation(), diag::note_delete_conversion)
4042 << ConvTy;
4043 }
4044
4048 llvm_unreachable("conversion functions are permitted");
4049 }
4050 } Converter;
4051
4056 if (!Converter.match(Type))
4057
4058
4060
4062 QualType PointeeElem = Context.getBaseElementType(Pointee);
4063
4067 diag::err_address_space_qualified_delete)
4070
4073
4074
4075
4076
4077 Diag(StartLoc, LangOpts.CPlusPlus26 ? diag::err_delete_incomplete
4078 : diag::ext_delete_void_ptr_operand)
4083 return ExprError(Diag(StartLoc, diag::err_delete_operand)
4086
4087
4091 ? diag::err_delete_incomplete
4092 : diag::warn_delete_incomplete,
4093 Ex.get())) {
4095 }
4096 }
4097
4098 if (Pointee->isArrayType() && !ArrayForm) {
4099 Diag(StartLoc, diag::warn_delete_array_type)
4102 ArrayForm = true;
4103 }
4104
4106 ArrayForm ? OO_Array_Delete : OO_Delete);
4107
4108 if (PointeeRD) {
4112 if (!UseGlobal &&
4114 OperatorDelete, IDP))
4116
4117
4118
4119 if (ArrayForm) {
4120
4121
4122 if (UseGlobal)
4125
4126
4127
4128 else if (isa_and_nonnull(OperatorDelete)) {
4129 UsualDeallocFnInfo UDFI(
4131 StartLoc);
4133 }
4134 }
4135
4138 if (Dtor->isCalledByDelete(OperatorDelete)) {
4142 }
4143 }
4144 }
4145
4147 true, true,
4148 !ArrayForm,
4150 }
4151
4152 if (!OperatorDelete) {
4154 Diag(StartLoc, diag::err_openclcxx_not_supported) << "default delete";
4156 }
4157
4158 bool IsComplete = isCompleteType(StartLoc, Pointee);
4159 bool CanProvideSize =
4160 IsComplete && (!ArrayForm || UsualArrayDeleteWantsSize ||
4163
4164
4170 if (!OperatorDelete)
4172 }
4173
4174 if (OperatorDelete->isInvalidDecl())
4176
4178
4179
4180
4181 bool IsVirtualDelete = false;
4182 if (PointeeRD) {
4184 if (Dtor->isCalledByDelete(OperatorDelete))
4186 PDiag(diag::err_access_dtor) << PointeeElem);
4187 IsVirtualDelete = Dtor->isVirtual();
4188 }
4189 }
4190
4192
4193 unsigned AddressParamIdx = 0;
4194 if (OperatorDelete->isTypeAwareOperatorNewOrDelete()) {
4195 QualType TypeIdentity = OperatorDelete->getParamDecl(0)->getType();
4197 diag::err_incomplete_type))
4199 AddressParamIdx = 1;
4200 }
4201
4202
4203
4204
4205
4207 OperatorDelete->getParamDecl(AddressParamIdx)->getType();
4211
4212
4217 }
4222 }
4223 }
4224
4226 Context.VoidTy, UseGlobal, ArrayForm, ArrayFormAsWritten,
4227 UsualArrayDeleteWantsSize, OperatorDelete, Ex.get(), StartLoc);
4228 AnalyzeDeleteExprMismatch(Result);
4230}
4231
4233 bool IsDelete,
4235
4237 IsDelete ? OO_Delete : OO_New);
4238
4241 assert(!R.empty() && "implicitly declared allocation functions not found");
4242 assert(!R.isAmbiguous() && "global allocation functions are ambiguous");
4243
4244
4246
4251 FnOvl != FnOvlEnd; ++FnOvl) {
4252
4253
4254 NamedDecl *D = (*FnOvl)->getUnderlyingDecl();
4255
4258 nullptr, Args,
4259 Candidates,
4260 false);
4261 continue;
4262 }
4263
4266 false);
4267 }
4268
4270
4271
4275
4278 "class members should not be considered");
4279
4281 S.Diag(R.getNameLoc(), diag::err_builtin_operator_new_delete_not_usual)
4282 << (IsDelete ? 1 : 0) << Range;
4283 S.Diag(FnDecl->getLocation(), diag::note_non_usual_function_declared_here)
4285 return true;
4286 }
4287
4288 Operator = FnDecl;
4289 return false;
4290 }
4291
4295 S.PDiag(diag::err_ovl_no_viable_function_in_call)
4298 return true;
4299
4303 S.PDiag(diag::err_ovl_ambiguous_call)
4306 return true;
4307
4310 Candidates, Best->Function, Args);
4311 return true;
4312 }
4313 llvm_unreachable("Unreachable, bad result from BestViableFunction");
4314}
4315
4316ExprResult Sema::BuiltinOperatorNewDeleteOverloaded(ExprResult TheCallResult,
4317 bool IsDelete) {
4320 Diag(TheCall->getExprLoc(), diag::err_builtin_requires_language)
4321 << (IsDelete ? "__builtin_operator_delete" : "__builtin_operator_new")
4322 << "C++";
4324 }
4325
4326
4328
4329 FunctionDecl *OperatorNewOrDelete = nullptr;
4331 OperatorNewOrDelete))
4333 assert(OperatorNewOrDelete && "should be found");
4334
4337
4339 for (unsigned i = 0; i != TheCall->getNumArgs(); ++i) {
4341 InitializedEntity Entity =
4348 }
4349 auto Callee = dyn_cast(TheCall->getCallee());
4350 assert(Callee && Callee->getCastKind() == CK_BuiltinFnToFnPtr &&
4351 "Callee expected to be implicit cast to a builtin function pointer");
4352 Callee->setType(OperatorNewOrDelete->getType());
4353
4354 return TheCallResult;
4355}
4356
4358 bool IsDelete, bool CallCanBeVirtual,
4359 bool WarnOnNonAbstractTypes,
4362 return;
4363
4364
4365
4366
4367
4368
4369
4370
4372
4374 return;
4375
4376
4377
4378
4380 return;
4381
4384
4385
4386 Diag(Loc, diag::warn_delete_abstract_non_virtual_dtor) << (IsDelete ? 0 : 1)
4387 << ClassType;
4388 } else if (WarnOnNonAbstractTypes) {
4389
4390
4391 Diag(Loc, diag::warn_delete_non_virtual_dtor) << (IsDelete ? 0 : 1)
4392 << ClassType;
4393 }
4394 if (!IsDelete) {
4395 std::string TypeStr;
4397 Diag(DtorLoc, diag::note_delete_non_virtual)
4399 }
4400}
4401
4413
4419
4421
4422
4423
4424 if (T->isFunctionType())
4426 diag::err_invalid_use_of_function_type)
4428 else if (T->isArrayType())
4430 diag::err_invalid_use_of_array_type)
4432
4436
4437 switch (CK) {
4440
4443
4446 }
4447
4448 llvm_unreachable("unexpected condition kind");
4449}
4450
4452
4453
4454
4455
4456
4457
4458
4459
4460
4461
4462
4463
4464
4465
4468 return E;
4469
4471 false,
4472 true);
4474 return E;
4475
4476
4477 llvm::APSInt Cond;
4480 diag::err_constexpr_if_condition_expression_is_not_constant);
4481 return E;
4482}
4483
4484bool
4486
4487 if (ImplicitCastExpr *Cast = dyn_cast(From))
4488 From = Cast->getSubExpr();
4489
4490
4491
4492
4493
4498
4499
4500 if (!ToPtrType->getPointeeType().hasQualifiers()) {
4501 switch (StrLit->getKind()) {
4505
4506 break;
4509 return (ToPointeeType->getKind() == BuiltinType::Char_U ||
4510 ToPointeeType->getKind() == BuiltinType::Char_S);
4512 return Context.typesAreCompatible(Context.getWideCharType(),
4513 QualType(ToPointeeType, 0));
4515 assert(false && "Unevaluated string literal in expression");
4516 break;
4517 }
4518 }
4519 }
4520
4521 return false;
4522}
4523
4530 bool HadMultipleCandidates,
4531 Expr *From) {
4532 switch (Kind) {
4533 default: llvm_unreachable("Unhandled cast kind!");
4534 case CK_ConstructorConversion: {
4537
4539 diag::err_allocation_of_abstract_type))
4541
4543 ConstructorArgs))
4545
4550
4553 ConstructorArgs, HadMultipleCandidates,
4554 false, false, false,
4556 if (Result.isInvalid())
4558
4560 }
4561
4562 case CK_UserDefinedConversion: {
4563 assert(!From->getType()->isPointerType() && "Arg can't have pointer type!");
4564
4568
4569
4572 HadMultipleCandidates);
4573 if (Result.isInvalid())
4575
4577 CK_UserDefinedConversion, Result.get(),
4578 nullptr, Result.get()->getValueKind(),
4580
4582 }
4583 }
4584}
4585
4591
4594 return From;
4595
4596 switch (ICS.getKind()) {
4599 Action, CCK);
4602 From = Res.get();
4603 break;
4604 }
4605
4607
4611 assert(FD && "no conversion function for user-defined conversion seq");
4612 if (const CXXConversionDecl *Conv = dyn_cast(FD)) {
4613 CastKind = CK_UserDefinedConversion;
4614
4615
4616
4617
4618 BeforeToType = Context.getCanonicalTagType(Conv->getParent());
4619 } else {
4621 CastKind = CK_ConstructorConversion;
4622
4624
4625
4626
4628 }
4629 }
4630
4637 From = Res.get();
4638 }
4639
4644
4647
4648 From = CastArg.get();
4649
4650
4651
4652
4654 return From;
4655
4658 }
4659
4662 PDiag(diag::err_typecheck_ambiguous_condition)
4665
4668 llvm_unreachable("bad conversion");
4669
4676 : ConvTy,
4678 assert(Diagnosed && "failed to diagnose bad conversion"); (void)Diagnosed;
4680 }
4681
4682
4683 return From;
4684}
4685
4686
4687
4692 ElType = ToVec->getElementType();
4693
4694 if (ElTy)
4695 *ElTy = ElType;
4697 return ElType;
4699 return Context.getExtVectorType(ElType, FromVec->getNumElements());
4700}
4701
4709
4710
4711
4712
4713
4715
4717
4723 SourceLocation(), ConstructorArgs))
4728 false,
4729 false, false, false,
4731 }
4735 false,
4736 false, false, false,
4738 }
4739
4740
4741 if (Context.hasSameType(FromType, Context.OverloadTy)) {
4745 if (!Fn)
4747
4750
4754
4755
4756
4760
4761 From = Res.get();
4762 FromType = From->getType();
4763 }
4764
4765
4766
4769 ToAtomicType = ToType;
4770 ToType = ToAtomic->getValueType();
4771 }
4772
4773 QualType InitialFromType = FromType;
4774
4775 switch (SCS.First) {
4778 FromType = FromAtomic->getValueType().getUnqualifiedType();
4780 From, nullptr, VK_PRValue,
4782 }
4783 break;
4784
4790
4791 From = FromRes.get();
4792 FromType = From->getType();
4793 break;
4794 }
4795
4797 FromType = Context.getArrayDecayedType(FromType);
4799 nullptr, CCK)
4801 break;
4802
4805 FromType = Context.getArrayParameterType(FromType);
4809 }
4811 nullptr, CCK)
4813 break;
4814
4816 FromType = Context.getPointerType(FromType);
4817 From = ImpCastExprToType(From, FromType, CK_FunctionToPointerDecay,
4818 VK_PRValue, nullptr, CCK)
4820 break;
4821
4822 default:
4823 llvm_unreachable("Improper first standard conversion");
4824 }
4825
4826
4827 switch (SCS.Second) {
4829
4830
4831
4832
4833
4834 switch (Action) {
4837
4844 break;
4845
4848
4849
4850 break;
4851 }
4852
4853 break;
4854
4864 "only enums with fixed underlying type can promote to bool");
4866 nullptr, CCK)
4868 } else {
4870 nullptr, CCK)
4872 }
4873 break;
4874 }
4875
4882 nullptr, CCK)
4884 break;
4885 }
4886
4894 CK = CK_FloatingComplexCast;
4895 else
4896 CK = CK_FloatingComplexToIntegralComplex;
4898 CK = CK_IntegralComplexToFloatingComplex;
4899 } else {
4900 CK = CK_IntegralComplexCast;
4901 }
4903 CCK)
4905 break;
4906 }
4907
4915 nullptr, CCK)
4917 else
4919 nullptr, CCK)
4921 break;
4922 }
4923
4926 "Attempting implicit fixed point conversion without a fixed "
4927 "point operand");
4931 nullptr, CCK).get();
4935 nullptr, CCK).get();
4939 nullptr, CCK).get();
4943 nullptr, CCK).get();
4947 nullptr, CCK).get();
4948 else
4951 nullptr, CCK).get();
4952 break;
4953
4956 nullptr, CCK).get();
4957 break;
4958
4962
4966 diag::ext_typecheck_convert_incompatible_pointer)
4968 << 0;
4969 else
4971 diag::ext_typecheck_convert_incompatible_pointer)
4973 << 0;
4974
4978 } else if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers() &&
4979 ().CheckObjCARCUnavailableWeakConversion(ToType,
4982 Diag(From->getBeginLoc(), diag::err_arc_weak_unavailable_assign);
4983 else
4984 Diag(From->getBeginLoc(), diag::err_arc_convesion_of_weak_unavailable)
4987 }
4988
4989
4992 QualType NewToType = ToType;
4993 if (!FromPteeType.isNull() && !ToPteeType.isNull() &&
4995 NewToType = Context.removeAddrSpaceQualType(ToPteeType);
4996 NewToType = Context.getAddrSpaceQualType(NewToType,
4999 NewToType = Context.getObjCObjectPointerType(NewToType);
5001 NewToType = Context.getBlockPointerType(NewToType);
5002 else
5003 NewToType = Context.getPointerType(NewToType);
5004 }
5005
5010
5011
5012
5013 if (Kind == CK_BlockPointerToObjCPointerCast) {
5016 From = E.get();
5017 }
5018 if (getLangOpts().allowsNonTrivialObjCLifetimeQualifiers())
5022 break;
5023 }
5024
5033 assert((Kind != CK_NullToMemberPointer ||
5036 "Expr must be null pointer constant!");
5037 break;
5039 break;
5041 llvm_unreachable("unexpected result");
5043 llvm_unreachable("Should not have been called if derivation isn't OK.");
5047 }
5050
5051 From =
5053 break;
5054 }
5055
5057
5060 FromType = Context.FloatTy;
5061 }
5069
5072 nullptr, CCK)
5074 break;
5075 }
5076
5083
5086 &BasePath, CCK).get();
5087 break;
5088 }
5089
5092 nullptr, CCK)
5094 break;
5095
5099 nullptr, CCK)
5101 break;
5102
5104
5107 nullptr, CCK)
5109 break;
5110 }
5111
5113
5115 QualType ElType = ToComplex->getElementType();
5117
5118
5119 if (Context.hasSameUnqualifiedType(ElType, From->getType())) {
5120
5123 isFloatingComplex ? CK_FloatingCast : CK_FloatingToIntegral).get();
5124 } else {
5127 isFloatingComplex ? CK_IntegralToFloating : CK_IntegralCast).get();
5128 }
5129
5131 isFloatingComplex ? CK_FloatingRealToComplex
5132 : CK_IntegralRealToComplex).get();
5133
5134
5135 } else {
5137 QualType ElType = FromComplex->getElementType();
5139
5140
5142 isFloatingComplex ? CK_FloatingComplexToReal
5143 : CK_IntegralComplexToReal,
5144 VK_PRValue, nullptr, CCK)
5146
5147
5148 if (Context.hasSameUnqualifiedType(ElType, ToType)) {
5149
5152 isFloatingComplex ? CK_FloatingCast
5153 : CK_IntegralToFloating,
5154 VK_PRValue, nullptr, CCK)
5156 } else {
5159 isFloatingComplex ? CK_FloatingToIntegral
5160 : CK_IntegralCast,
5161 VK_PRValue, nullptr, CCK)
5163 }
5164 }
5165 break;
5166
5174 "Invalid cast");
5176 AddrSpaceL != AddrSpaceR ? CK_AddressSpaceConversion : CK_BitCast;
5178 VK_PRValue, nullptr, CCK)
5180 break;
5181 }
5182
5189 From = FromRes.get();
5191 "Improper transparent union conversion");
5192 (void)ConvTy;
5193 break;
5194 }
5195
5199 CK_ZeroToOCLOpaqueType,
5201 break;
5202
5215 llvm_unreachable("Improper second standard conversion");
5216 }
5217
5219
5220
5221 assert(
5224 "Dimension conversion output must be vector, matrix, or scalar type.");
5227
5230 nullptr, CCK)
5232 break;
5233 }
5235
5236
5237
5238
5239
5241 QualType TruncTy = FromVec->getElementType();
5243 TruncTy = Context.getExtVectorType(TruncTy, ToVec->getNumElements());
5244 From = ImpCastExprToType(From, TruncTy, CK_HLSLVectorTruncation,
5247
5248 break;
5249 }
5252 QualType TruncTy = FromMat->getElementType();
5254 TruncTy = Context.getConstantMatrixType(TruncTy, ToMat->getNumRows(),
5255 ToMat->getNumColumns());
5256 From = ImpCastExprToType(From, TruncTy, CK_HLSLMatrixTruncation,
5259 break;
5260 }
5262 default:
5263 llvm_unreachable("Improper element standard conversion");
5264 }
5265 }
5266
5267 switch (SCS.Third) {
5269
5270 break;
5271
5273
5274
5277
5279 nullptr, CCK)
5281 break;
5282
5286
5290 CK = CK_AddressSpaceConversion;
5291
5295 CK = CK_AddressSpaceConversion;
5296
5300 Diag(From->getBeginLoc(), diag::warn_imp_cast_drops_unaligned)
5301 << InitialFromType << ToType;
5302 }
5303
5305 nullptr, CCK)
5307
5312 ? diag::ext_deprecated_string_literal_conversion
5313 : diag::warn_deprecated_string_literal_conversion)
5315 }
5316
5317 break;
5318 }
5319
5320 default:
5321 llvm_unreachable("Improper third standard conversion");
5322 }
5323
5324
5325
5326 if (!ToAtomicType.isNull()) {
5327 assert(Context.hasSameType(
5329 From = ImpCastExprToType(From, ToAtomicType, CK_NonAtomicToAtomic,
5332 }
5333
5334
5335
5336
5341 From = Res.get();
5342 }
5343
5344
5345
5349
5350 return From;
5351}
5352
5356 bool isIndirect) {
5358 "placeholders should have been weeded out by now");
5359
5360
5361
5362 if (isIndirect)
5368
5369
5372
5373 const char *OpSpelling = isIndirect ? "->*" : ".*";
5374
5375
5376
5377
5380 if (!MemPtr) {
5381 Diag(Loc, diag::err_bad_memptr_rhs)
5384 }
5385
5387
5388
5389
5390
5391
5392
5393
5394
5395
5396
5397
5399 if (isIndirect) {
5402 else {
5403 Diag(Loc, diag::err_bad_memptr_lhs)
5404 << OpSpelling << 1 << LHSType
5407 }
5408 }
5410
5412
5414 OpSpelling, (int)isIndirect)) {
5416 }
5417
5419 Diag(Loc, diag::err_bad_memptr_lhs) << OpSpelling
5420 << (int)isIndirect << LHS.get()->getType();
5422 }
5423
5424
5428 LHSType, RHSClassType, Loc,
5430 &BasePath))
5432
5433
5436 if (isIndirect)
5437 UseType = Context.getPointerType(UseType);
5440 &BasePath);
5441 }
5442
5444
5445
5446 Diag(Loc, diag::err_pointer_to_member_type) << isIndirect;
5448 }
5449
5450
5451
5452
5453
5454
5457
5458
5459
5460
5461
5462
5463
5465 switch (Proto->getRefQualifier()) {
5467
5468 break;
5469
5472
5473
5474 if (Proto->isConst() && !Proto->isVolatile())
5476 ? diag::warn_cxx17_compat_pointer_to_const_ref_member_on_rvalue
5477 : diag::ext_pointer_to_const_ref_member_on_rvalue);
5478 else
5479 Diag(Loc, diag::err_pointer_to_member_oper_value_classify)
5481 }
5482 break;
5483
5486 Diag(Loc, diag::err_pointer_to_member_oper_value_classify)
5488 break;
5489 }
5490 }
5491
5492
5493
5494
5495
5496
5497
5498
5499 if (Result->isFunctionType()) {
5501 return Context.BoundMemberTy;
5502 } else if (isIndirect) {
5504 } else {
5506 }
5507
5509}
5510
5511
5512
5513
5514
5515
5516
5517
5520 bool &HaveConversion,
5522 HaveConversion = false;
5524
5527
5528
5529
5530
5531
5532
5533
5534
5535
5536
5537
5539 QualType T = Self.Context.getReferenceQualifiedType(To);
5541
5544 ToType = T;
5545 HaveConversion = true;
5546 return false;
5547 }
5548
5550 return InitSeq.Diagnose(Self, Entity, Kind, From);
5551 }
5552
5553
5554
5555
5558 const RecordType *FRec = FTy->getAsCanonical();
5559 const RecordType *TRec = TTy->getAsCanonical();
5560 bool FDerivedFromT = FRec && TRec && FRec != TRec &&
5561 Self.IsDerivedFrom(QuestionLoc, FTy, TTy);
5562 if (FRec && TRec && (FRec == TRec || FDerivedFromT ||
5563 Self.IsDerivedFrom(QuestionLoc, TTy, FTy))) {
5564
5565
5566
5567 if (FRec == TRec || FDerivedFromT) {
5571 if (InitSeq) {
5572 HaveConversion = true;
5573 return false;
5574 }
5575
5577 return InitSeq.Diagnose(Self, Entity, Kind, From);
5578 }
5579 }
5580
5581 return false;
5582 }
5583
5584
5585
5586
5587
5588
5589
5590
5592
5595 HaveConversion = !InitSeq.Failed();
5596 ToType = TTy;
5598 return InitSeq.Diagnose(Self, Entity, Kind, From);
5599
5600 return false;
5601}
5602
5603
5604
5605
5606
5607
5610 Expr *Args[2] = { LHS.get(), RHS.get() };
5613 Self.AddBuiltinOperatorCandidates(OO_Conditional, QuestionLoc, Args,
5614 CandidateSet);
5615
5619
5621 LHS.get(), Best->BuiltinParamTypes[0], Best->Conversions[0],
5624 break;
5625 LHS = LHSRes;
5626
5628 RHS.get(), Best->BuiltinParamTypes[1], Best->Conversions[1],
5631 break;
5632 RHS = RHSRes;
5633 if (Best->Function)
5634 Self.MarkFunctionReferenced(QuestionLoc, Best->Function);
5635 return false;
5636 }
5637
5639
5640
5641
5642
5643 if (Self.DiagnoseConditionalForNull(LHS.get(), RHS.get(), QuestionLoc))
5644 return true;
5645
5646 Self.Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
5649 return true;
5650
5652 Self.Diag(QuestionLoc, diag::err_conditional_ambiguous_ovl)
5655
5656
5657 break;
5658
5660 llvm_unreachable("Conditional operator has only built-in overloads");
5661 }
5662 return true;
5663}
5664
5665
5666
5674 if (Result.isInvalid())
5675 return true;
5676
5677 E = Result;
5678 return false;
5679}
5680
5681
5682
5687 return false;
5689 IsSVEVectorType
5692 assert(!EltTy->isEnumeralType() && "Vectors cant be enum types");
5694}
5695
5701
5705
5708 bool LHSIsVector = LHSType->isVectorType() || LHSSizelessVector;
5709 bool RHSIsVector = RHSType->isVectorType() || RHSSizelessVector;
5710
5711 auto GetVectorInfo =
5712 [&](QualType Type) -> std::pair<QualType, llvm::ElementCount> {
5714 return std::make_pair(VT->getElementType(),
5715 llvm::ElementCount::getFixed(VT->getNumElements()));
5718 return std::make_pair(VectorInfo.ElementType, VectorInfo.EC);
5719 };
5720
5721 auto [CondElementTy, CondElementCount] = GetVectorInfo(CondType);
5722
5724 if (LHSIsVector && RHSIsVector) {
5726 Diag(QuestionLoc, diag::err_conditional_vector_cond_result_mismatch)
5727 << 1;
5728 return {};
5729 }
5730
5731
5732 if (.hasSameType(LHSType, RHSType)) {
5733 Diag(QuestionLoc, diag::err_conditional_vector_mismatched)
5734 << LHSType << RHSType;
5735 return {};
5736 }
5737 ResultType = Context.getCommonSugaredType(LHSType, RHSType);
5738 } else if (LHSIsVector || RHSIsVector) {
5739 bool ResultSizeless = LHSSizelessVector || RHSSizelessVector;
5741 Diag(QuestionLoc, diag::err_conditional_vector_cond_result_mismatch)
5742 << 0;
5743 return {};
5744 }
5745 if (ResultSizeless)
5747 false,
5749 else
5751 LHS, RHS, QuestionLoc, false, true,
5752 false,
5753 true,
5754 true);
5755 if (ResultType.isNull())
5756 return {};
5757 } else {
5758
5762 Context.hasSameType(LHSType, RHSType)
5763 ? Context.getCommonSugaredType(LHSType, RHSType)
5766
5768 Diag(QuestionLoc, diag::err_conditional_vector_operand_type)
5769 << ResultElementTy;
5770 return {};
5771 }
5773 ResultType = Context.getExtVectorType(ResultElementTy,
5774 CondElementCount.getFixedValue());
5776 ResultType = Context.getScalableVectorType(
5777 ResultElementTy, CondElementCount.getKnownMinValue());
5778
5779 if (ResultType.isNull()) {
5780 Diag(QuestionLoc, diag::err_conditional_vector_scalar_type_unsupported)
5781 << ResultElementTy << CondType;
5782 return {};
5783 }
5784 } else {
5785 ResultType = Context.getVectorType(ResultElementTy,
5786 CondElementCount.getFixedValue(),
5788 }
5791 }
5792
5793 assert(!ResultType.isNull() &&
5796 "Result should have been a vector type");
5797
5798 auto [ResultElementTy, ResultElementCount] = GetVectorInfo(ResultType);
5799 if (ResultElementCount != CondElementCount) {
5800 Diag(QuestionLoc, diag::err_conditional_vector_size) << CondType
5801 << ResultType;
5802 return {};
5803 }
5804
5805
5806 if (Context.getTypeSize(ResultElementTy) !=
5807 Context.getTypeSize(CondElementTy) &&
5808 (!CondElementTy->isBooleanType() || LangOpts.OpenCL)) {
5809 Diag(QuestionLoc, diag::err_conditional_vector_element_size)
5810 << CondType << ResultType;
5811 return {};
5812 }
5813
5814 return ResultType;
5815}
5816
5821
5822
5823
5824
5827 bool IsVectorConditional =
5829
5830
5831
5832 if (.get()->isTypeDependent()) {
5833 ExprResult CondRes = IsVectorConditional
5838 Cond = CondRes;
5839 } else {
5840
5841
5842
5843
5844
5845 return Context.DependentTy;
5846 }
5847
5848
5849
5851 return Context.DependentTy;
5852
5853
5854
5859 if (LVoid || RVoid) {
5860
5861
5862
5863
5866
5867
5868 if (IsVectorConditional) {
5871 bool IsThrow = LVoid ? LThrow : RThrow;
5872 Diag(DiagLoc.getBegin(), diag::err_conditional_vector_has_void)
5873 << DiagLoc << IsThrow;
5875 }
5876
5877 if (LThrow != RThrow) {
5878 Expr *NonThrow = LThrow ? RHS.get() : LHS.get();
5880
5881
5883 return NonThrow->getType();
5884 }
5885
5886
5887
5888 if (LVoid && RVoid)
5889 return Context.getCommonSugaredType(LTy, RTy);
5890
5891
5892 Diag(QuestionLoc, diag::err_conditional_void_nonvoid)
5893 << (LVoid ? RTy : LTy) << (LVoid ? 0 : 1)
5896 }
5897
5898
5899 if (IsVectorConditional)
5901
5902
5904 Diag(QuestionLoc, diag::err_wasm_table_conditional_expression)
5907 }
5908
5909
5910
5911
5912
5913 if (.hasSameType(LTy, RTy) &&
5915
5917 bool HaveL2R, HaveR2L;
5922
5923
5924 if (HaveL2R && HaveR2L) {
5925 Diag(QuestionLoc, diag::err_conditional_ambiguous)
5928 }
5929
5930
5931
5932
5933 if (HaveL2R) {
5937 } else if (HaveR2L) {
5941 }
5942 }
5943
5944
5945
5946
5947
5948
5949
5950
5951
5952
5953
5954
5957 if (.hasSameType(LTy, RTy) && LVK == RVK && LVK != VK_PRValue) {
5958
5959
5961 ReferenceConversions::Qualification |
5962 ReferenceConversions::NestedQualification |
5963 ReferenceConversions::Function;
5964
5968 !(RefConv & ~AllowedConversions) &&
5969
5970
5976 !(RefConv & ~AllowedConversions) &&
5981 }
5982 }
5983
5984
5985
5986
5987
5988
5989
5990
5991 bool Same = Context.hasSameType(LTy, RTy);
5992 if (Same && LVK == RVK && LVK != VK_PRValue &&
5999 return Context.getCommonSugaredType(LTy, RTy);
6000 }
6001
6002
6003
6004
6006
6007
6008
6011 }
6012
6013
6014
6015
6022
6023
6024
6025
6026
6027
6028
6029 if (Context.hasSameType(LTy, RTy)) {
6031
6036
6041
6042 LHS = LHSCopy;
6043 RHS = RHSCopy;
6044 }
6045 return Context.getCommonSugaredType(LTy, RTy);
6046 }
6047
6048
6050 return CheckVectorOperands(LHS, RHS, QuestionLoc, false,
6051 true,
6052 false,
6053 false,
6054 true);
6055
6056
6057
6058
6064 if (ResTy.isNull()) {
6065 Diag(QuestionLoc,
6066 diag::err_typecheck_cond_incompatible_operands) << LTy << RTy
6069 }
6070
6073
6074 return ResTy;
6075 }
6076
6077
6078
6079
6080
6081
6082
6083
6084
6085
6086
6087
6088
6090 if (!Composite.isNull())
6091 return Composite;
6092
6093
6097 if (!Composite.isNull())
6098 return Composite;
6099
6100
6103
6104 Diag(QuestionLoc, diag::err_typecheck_cond_incompatible_operands)
6108}
6109
6112 bool ConvertArgs) {
6114
6115
6116
6117
6119
6120
6121
6124 bool T2IsPointerLike = T2->isAnyPointerType() || T2->isMemberPointerType() ||
6125 T2->isNullPtrType();
6126 if (!T1IsPointerLike && !T2IsPointerLike)
6128
6129
6130
6131
6132
6133
6134 if (T1IsPointerLike &&
6136 if (ConvertArgs)
6138 ? CK_NullToMemberPointer
6139 : CK_NullToPointer).get();
6140 return T1;
6141 }
6142 if (T2IsPointerLike &&
6144 if (ConvertArgs)
6146 ? CK_NullToMemberPointer
6147 : CK_NullToPointer).get();
6148 return T2;
6149 }
6150
6151
6152 if (!T1IsPointerLike || !T2IsPointerLike)
6154 assert(!T1->isNullPtrType() && !T2->isNullPtrType() &&
6155 "nullptr_t should be a null pointer constant");
6156
6157 struct Step {
6158 enum Kind { Pointer, ObjCPointer, MemberPointer, Array } K;
6159
6161
6162
6163
6164 const Type *ClassOrBound;
6165
6166 Step(Kind K, const Type *ClassOrBound = nullptr)
6167 : K(K), ClassOrBound(ClassOrBound) {}
6170 switch (K) {
6173 case MemberPointer:
6176 case ObjCPointer:
6178 case Array:
6179 if (auto *CAT = cast_or_null(ClassOrBound))
6182 else
6184 }
6185 llvm_unreachable("unknown step kind");
6186 }
6187 };
6188
6190
6191
6192
6193
6194
6195
6196
6197
6198
6199
6200
6201
6202
6203
6204
6207 unsigned NeedConstBefore = 0;
6208 while (true) {
6209 assert(!Composite1.isNull() && !Composite2.isNull());
6210
6212 Composite1 = Context.getUnqualifiedArrayType(Composite1, Q1);
6213 Composite2 = Context.getUnqualifiedArrayType(Composite2, Q2);
6214
6215
6216 if (!Steps.empty()) {
6217
6218
6221
6222
6223
6226 } else if (Steps.size() == 1) {
6229 if (MaybeQ1 == MaybeQ2) {
6230
6231
6234 MaybeQ1 = true;
6235 else
6236 return QualType();
6237 }
6240 } else {
6242 }
6243
6244
6248 assert(Steps.size() == 1);
6249 else
6251
6252
6256 assert(Steps.size() == 1);
6257 else
6259
6262 else
6264
6265 Steps.back().Quals = Quals;
6266 if (Q1 != Quals || Q2 != Quals)
6267 NeedConstBefore = Steps.size() - 1;
6268 }
6269
6270
6271
6273 if ((Arr1 = Context.getAsArrayType(Composite1)) &&
6274 (Arr2 = Context.getAsArrayType(Composite2))) {
6275 auto *CAT1 = dyn_cast(Arr1);
6276 auto *CAT2 = dyn_cast(Arr2);
6277 if (CAT1 && CAT2 && CAT1->getSize() == CAT2->getSize()) {
6280 Steps.emplace_back(Step::Array, CAT1);
6281 continue;
6282 }
6285 if ((IAT1 && IAT2) ||
6287 ((bool)CAT1 != (bool)CAT2) &&
6288 (Steps.empty() || Steps.back().K != Step::Array))) {
6289
6290
6291
6294 Steps.emplace_back(Step::Array);
6295 if (CAT1 || CAT2)
6296 NeedConstBefore = Steps.size();
6297 continue;
6298 }
6299 }
6300
6306 Steps.emplace_back(Step::Pointer);
6307 continue;
6308 }
6309
6315 Steps.emplace_back(Step::ObjCPointer);
6316 continue;
6317 }
6318
6324
6325
6326
6327
6328
6329
6330
6331
6332
6333
6338 Cls = Cls1;
6339 else if (Steps.empty())
6342 : nullptr;
6343 if (!Cls)
6345
6346 Steps.emplace_back(Step::MemberPointer,
6347 Context.getCanonicalTagType(Cls).getTypePtr());
6348 continue;
6349 }
6350
6351
6352
6359 Steps.emplace_back(Step::Pointer);
6360 continue;
6361 }
6362
6363
6364
6365
6366 break;
6367 }
6368
6369
6370
6371
6372
6373
6374
6375
6376
6377
6378
6379
6380
6381
6382
6383
6384
6385
6386
6387
6388
6389
6390
6391
6392
6393
6394
6395
6396
6397 if (Steps.size() == 1) {
6402
6403
6404 bool Noreturn =
6408
6409 bool CFIUncheckedCallee =
6413
6414
6419
6420 Composite1 = Context.getFunctionType(FPT1->getReturnType(),
6421 FPT1->getParamTypes(), EPI1);
6422 Composite2 = Context.getFunctionType(FPT2->getReturnType(),
6423 FPT2->getParamTypes(), EPI2);
6424 }
6425 }
6426 }
6427
6428
6429 if (Steps.size() == 1 && Steps.front().K == Step::Pointer &&
6430 .hasSameType(Composite1, Composite2)) {
6431
6432
6433
6435 Composite2 = Composite1;
6437 Composite1 = Composite2;
6438
6439
6440
6441
6442
6443
6444
6445 else if (IsDerivedFrom(Loc, Composite1, Composite2))
6446 Composite1 = Composite2;
6447 else if (IsDerivedFrom(Loc, Composite2, Composite1))
6448 Composite2 = Composite1;
6449 }
6450
6451
6452
6453 if (.hasSameType(Composite1, Composite2))
6455
6456
6457
6458 for (unsigned I = 0; I != NeedConstBefore; ++I)
6459 Steps[I].Quals.addConst();
6460
6461
6462 QualType Composite = Context.getCommonSugaredType(Composite1, Composite2);
6463 for (auto &S : llvm::reverse(Steps))
6464 Composite = S.rebuild(Context, Composite);
6465
6466 if (ConvertArgs) {
6467
6472
6474 if (!E1ToC)
6476
6478 if (!E2ToC)
6480
6481
6485 E1 = E1Result.get();
6486
6490 E2 = E2Result.get();
6491 }
6492
6493 return Composite;
6494}
6495
6497 if (!E)
6499
6501
6502
6504 return E;
6505
6506
6507
6510
6511 bool ReturnsRetained;
6512
6513
6514
6515 if (CallExpr *Call = dyn_cast(E)) {
6516 Expr *Callee = Call->getCallee()->IgnoreParens();
6518
6519 if (T == Context.BoundMemberTy) {
6520
6521 if (BinaryOperator *BinOp = dyn_cast(Callee))
6522 T = BinOp->getRHS()->getType();
6523 else if (MemberExpr *Mem = dyn_cast(Callee))
6524 T = Mem->getMemberDecl()->getType();
6525 }
6526
6528 T = Ptr->getPointeeType();
6530 T = Ptr->getPointeeType();
6532 T = MemPtr->getPointeeType();
6533
6535 ReturnsRetained = FTy->getExtInfo().getProducesResult();
6536
6537
6538
6540 ReturnsRetained = true;
6541
6542
6543
6546 return E;
6547
6548
6549
6550
6551 } else {
6553 if (ObjCMessageExpr *Send = dyn_cast(E)) {
6554 D = Send->getMethodDecl();
6555 } else if (ObjCBoxedExpr *BoxedExpr = dyn_cast(E)) {
6556 D = BoxedExpr->getBoxingMethod();
6557 } else if (ObjCArrayLiteral *ArrayLit = dyn_cast(E)) {
6558
6559
6560 if (ArrayLit->getNumElements() == 0 &&
6561 Context.getLangOpts().ObjCRuntime.hasEmptyCollections())
6562 return E;
6563
6564 D = ArrayLit->getArrayWithObjectsMethod();
6566 = dyn_cast(E)) {
6567
6568
6569 if (DictLit->getNumElements() == 0 &&
6570 Context.getLangOpts().ObjCRuntime.hasEmptyCollections())
6571 return E;
6572
6573 D = DictLit->getDictWithObjectsMethod();
6574 }
6575
6576 ReturnsRetained = (D && D->hasAttr());
6577
6578
6579
6580
6581 if (!ReturnsRetained &&
6583 return E;
6584 }
6585
6586
6588 return E;
6589
6590 Cleanup.setExprNeedsCleanups(true);
6591
6592 CastKind ck = (ReturnsRetained ? CK_ARCConsumeObject
6593 : CK_ARCReclaimReturnedObject);
6596 }
6597
6599 Cleanup.setExprNeedsCleanups(true);
6600
6602 return E;
6603
6604
6605
6607 const RecordType *RT = nullptr;
6608 while (!RT) {
6609 switch (T->getTypeClass()) {
6610 case Type::Record:
6612 break;
6613 case Type::ConstantArray:
6614 case Type::IncompleteArray:
6615 case Type::VariableArray:
6616 case Type::DependentSizedArray:
6618 break;
6619 default:
6620 return E;
6621 }
6622 }
6623
6624
6625
6628 return E;
6629
6633
6637 PDiag(diag::err_access_dtor_temp)
6641
6642
6644 return E;
6645
6646
6647 Cleanup.setExprNeedsCleanups(true);
6648 }
6649
6652
6653 if (IsDecltype)
6655
6656 return Bind;
6657}
6658
6666
6668 assert(SubExpr && "subexpression can't be null!");
6669
6671
6672 unsigned FirstCleanup = ExprEvalContexts.back().NumCleanupObjects;
6674 assert(Cleanup.exprNeedsCleanups() ||
6676 if (.exprNeedsCleanups())
6677 return SubExpr;
6678
6681
6683 Context, SubExpr, Cleanup.cleanupsHaveSideEffects(), Cleanups);
6685
6686 return E;
6687}
6688
6690 assert(SubStmt && "sub-statement can't be null!");
6691
6693
6694 if (.exprNeedsCleanups())
6695 return SubStmt;
6696
6697
6698
6699
6700
6706 0);
6708}
6709
6713 "not in a decltype expression");
6714
6716 if (Result.isInvalid())
6719
6720
6721
6722
6723
6724
6725
6726
6727
6728
6729
6730 if (ParenExpr *PE = dyn_cast(E)) {
6734 if (SubExpr.get() == PE->getSubExpr())
6735 return E;
6736 return ActOnParenExpr(PE->getLParen(), PE->getRParen(), SubExpr.get());
6737 }
6738 if (BinaryOperator *BO = dyn_cast(E)) {
6739 if (BO->getOpcode() == BO_Comma) {
6743 if (RHS.get() == BO->getRHS())
6744 return E;
6746 BO->getType(), BO->getValueKind(),
6747 BO->getObjectKind(), BO->getOperatorLoc(),
6748 BO->getFPFeatures());
6749 }
6750 }
6751
6753 CallExpr *TopCall = TopBind ? dyn_cast(TopBind->getSubExpr())
6754 : nullptr;
6755 if (TopCall)
6756 E = TopCall;
6757 else
6758 TopBind = nullptr;
6759
6760
6763
6765 if (Result.isInvalid())
6768
6769
6770
6772 return E;
6773
6774
6775 for (unsigned I = 0, N = ExprEvalContexts.back().DelayedDecltypeCalls.size();
6776 I != N; ++I) {
6778 if (Call == TopCall)
6779 continue;
6780
6782 Call->getBeginLoc(), Call, Call->getDirectCallee()))
6784 }
6785
6786
6787
6788 for (unsigned I = 0, N = ExprEvalContexts.back().DelayedDecltypeBinds.size();
6789 I != N; ++I) {
6792 if (Bind == TopBind)
6793 continue;
6794
6796
6798 Bind->getType()->getBaseElementTypeUnsafe()->getAsCXXRecordDecl();
6801
6804 PDiag(diag::err_access_dtor_temp)
6805 << Bind->getType());
6808
6809
6810 Cleanup.setExprNeedsCleanups(true);
6811 }
6812
6813
6814 return E;
6815}
6816
6817
6820 unsigned SkipStart = OperatorArrows.size(), SkipCount = 0;
6821
6822 unsigned Limit = 9;
6823 if (OperatorArrows.size() > Limit) {
6824
6825 SkipStart = (Limit - 1) / 2 + (Limit - 1) % 2;
6826 SkipCount = OperatorArrows.size() - (Limit - 1);
6827 }
6828
6829 for (unsigned I = 0; I < OperatorArrows.size(); ) {
6830 if (I == SkipStart) {
6831 S.Diag(OperatorArrows[I]->getLocation(),
6832 diag::note_operator_arrows_suppressed)
6833 << SkipCount;
6834 I += SkipCount;
6835 } else {
6836 S.Diag(OperatorArrows[I]->getLocation(), diag::note_operator_arrow_here)
6837 << OperatorArrows[I]->getCallResultType();
6838 ++I;
6839 }
6840 }
6841}
6842
6847 bool &MayBePseudoDestructor) {
6848
6852
6856
6858 MayBePseudoDestructor = false;
6859 if (BaseType->isDependentType()) {
6860
6861
6862
6863 if (OpKind == tok::arrow)
6865 BaseType = Ptr->getPointeeType();
6866
6868 MayBePseudoDestructor = true;
6869 return Base;
6870 }
6871
6872
6873
6874
6875 if (OpKind == tok::arrow) {
6876 QualType StartingType = BaseType;
6877 bool NoArrowOperatorFound = false;
6878 bool FirstIteration = true;
6880
6883 CTypes.insert(Context.getCanonicalType(BaseType));
6884
6885 while (BaseType->isRecordType()) {
6886 if (OperatorArrows.size() >= getLangOpts().ArrowDepth) {
6887 Diag(OpLoc, diag::err_operator_arrow_depth_exceeded)
6888 << StartingType << getLangOpts().ArrowDepth << Base->getSourceRange();
6890 Diag(OpLoc, diag::note_operator_arrow_depth)
6893 }
6894
6896 S, Base, OpLoc,
6897
6898
6899
6900
6902 ? nullptr
6903 : &NoArrowOperatorFound);
6904 if (Result.isInvalid()) {
6905 if (NoArrowOperatorFound) {
6906 if (FirstIteration) {
6907 Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
6908 << BaseType << 1 << Base->getSourceRange()
6910 OpKind = tok::period;
6911 break;
6912 }
6913 Diag(OpLoc, diag::err_typecheck_member_reference_arrow)
6914 << BaseType << Base->getSourceRange();
6918 diag::note_member_reference_arrow_from_operator_arrow);
6919 }
6920 }
6922 }
6925 OperatorArrows.push_back(OpCall->getDirectCallee());
6926 BaseType = Base->getType();
6928 if (!CTypes.insert(CBaseType).second) {
6929 Diag(OpLoc, diag::err_operator_arrow_circular) << StartingType;
6932 }
6933 FirstIteration = false;
6934 }
6935
6936 if (OpKind == tok::arrow) {
6937 if (BaseType->isPointerType())
6938 BaseType = BaseType->getPointeeType();
6939 else if (auto *AT = Context.getAsArrayType(BaseType))
6940 BaseType = AT->getElementType();
6941 }
6942 }
6943
6944
6945
6946 if (BaseType->isObjCObjectPointerType())
6947 BaseType = BaseType->getPointeeType();
6948
6949
6950
6951
6952
6953
6954
6955
6956
6957
6958
6959
6960 if (!BaseType->isRecordType()) {
6962 MayBePseudoDestructor = true;
6963 return Base;
6964 }
6965
6966
6967
6968
6969
6970
6971 if (!BaseType->isDependentType() &&
6974 diag::err_incomplete_member_access)) {
6976 }
6977
6978
6979
6980
6981
6982
6984 return Base;
6985}
6986
6989 if (Base->hasPlaceholderType()) {
6991 if (result.isInvalid()) return true;
6993 }
6994 ObjectType = Base->getType();
6995
6996
6997
6998
6999
7000
7001
7002 if (OpKind == tok::arrow) {
7003
7004
7005
7010 return true;
7012 ObjectType = Base->getType();
7013 }
7014
7017 } else if (->isTypeDependent()) {
7018
7019 S.Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
7020 << ObjectType << true
7023 return true;
7024
7025 OpKind = tok::period;
7026 }
7027 }
7028
7029 return false;
7030}
7031
7032
7033
7034static bool
7037
7041 return SemaRef.CanUseDecl(D, false);
7042 return false;
7043 }
7044
7045
7048}
7049
7059
7061 if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc))
7063
7067 Diag(OpLoc, diag::ext_pseudo_dtor_on_void) << Base->getSourceRange();
7068 else {
7069 Diag(OpLoc, diag::err_pseudo_dtor_base_not_scalar)
7070 << ObjectType << Base->getSourceRange();
7072 }
7073 }
7074
7075
7076
7077
7078 if (DestructedTypeInfo) {
7079 QualType DestructedType = DestructedTypeInfo->getType();
7083 if (.hasSameUnqualifiedType(DestructedType, ObjectType)) {
7084
7085
7086
7087 if (OpKind == tok::period && ObjectType->isPointerType() &&
7088 Context.hasSameUnqualifiedType(DestructedType,
7091 Diag(OpLoc, diag::err_typecheck_member_reference_suggestion)
7092 << ObjectType << 0 << Base->getSourceRange();
7093
7094
7096 *this, DestructedType))
7098
7099
7100
7101 ObjectType = DestructedType;
7102 OpKind = tok::arrow;
7103 } else {
7104 Diag(DestructedTypeStart, diag::err_pseudo_dtor_type_mismatch)
7105 << ObjectType << DestructedType << Base->getSourceRange()
7107
7108
7109 DestructedType = ObjectType;
7110 DestructedTypeInfo =
7111 Context.getTrivialTypeSourceInfo(ObjectType, DestructedTypeStart);
7113 }
7116
7118
7119
7120 } else {
7121 Diag(DestructedTypeStart, diag::err_arc_pseudo_dtor_inconstant_quals)
7122 << ObjectType << DestructedType << Base->getSourceRange()
7124 }
7125
7126
7127 DestructedType = ObjectType;
7128 DestructedTypeInfo = Context.getTrivialTypeSourceInfo(ObjectType,
7129 DestructedTypeStart);
7131 }
7132 }
7133 }
7134
7135
7136
7137
7138
7139
7140
7141
7142 if (ScopeTypeInfo) {
7144 if (!ScopeType->isDependentType() && !ObjectType->isDependentType() &&
7145 .hasSameUnqualifiedType(ScopeType, ObjectType)) {
7146
7148 diag::err_pseudo_dtor_type_mismatch)
7149 << ObjectType << ScopeType << Base->getSourceRange()
7151
7153 ScopeTypeInfo = nullptr;
7154 }
7155 }
7156
7159 OpKind == tok::arrow, OpLoc,
7161 ScopeTypeInfo,
7162 CCLoc,
7163 TildeLoc,
7164 Destructed);
7165
7167}
7168
7179 "Invalid first type name in pseudo-destructor");
7182 "Invalid second type name in pseudo-destructor");
7183
7185 if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc))
7187
7188
7189
7191 if (!SS.isSet()) {
7196 }
7197
7198
7199
7206 S, &SS, true, false, ObjectTypePtrForLookup,
7207 true);
7208 if ( &&
7211
7212
7213
7214
7217 } else if () {
7219 diag::err_pseudo_dtor_destructor_non_type)
7220 << SecondTypeName.Identifier << ObjectType;
7223
7224
7225 DestructedType = ObjectType;
7226 } else
7228 } else {
7229
7239 true);
7240 if (T.isInvalid() || .get()) {
7241
7242 DestructedType = ObjectType;
7243 } else
7245 }
7246
7247
7248
7249 if (!DestructedType.isNull()) {
7250 if (!DestructedTypeInfo)
7251 DestructedTypeInfo = Context.getTrivialTypeSourceInfo(DestructedType,
7254 }
7255
7256
7264 S, &SS, true, false, ObjectTypePtrForLookup,
7265 true);
7266 if () {
7268 diag::err_pseudo_dtor_destructor_non_type)
7269 << FirstTypeName.Identifier << ObjectType;
7270
7273
7274
7276 } else
7278 } else {
7279
7289 true);
7290 if (T.isInvalid() || .get()) {
7291
7293 } else
7295 }
7296 }
7297
7298 if (!ScopeType.isNull() && !ScopeTypeInfo)
7299 ScopeTypeInfo = Context.getTrivialTypeSourceInfo(ScopeType,
7301
7302
7304 ScopeTypeInfo, CCLoc, TildeLoc,
7305 Destructed);
7306}
7307
7316 if (CheckArrow(*this, ObjectType, Base, OpKind, OpLoc) ||
7319
7323 return true;
7324 }
7330 break;
7331 }
7340 break;
7341 }
7342 default:
7343 llvm_unreachable("Unsupported type in pseudo destructor");
7344 }
7347
7350 Destructed);
7351}
7352
7355
7356
7357
7360 return R;
7361
7365
7366 Operand = R.get();
7367
7369 Operand->HasSideEffects(Context, false)) {
7370
7371
7372 Diag(Operand->getExprLoc(), diag::warn_side_effects_unevaluated_context);
7373 }
7374
7378}
7379
7384
7388 bool IsCompoundAssign = false;
7389 bool isIncrementDecrementUnaryOp = false;
7390 if (BinaryOperator *BO = dyn_cast(E)) {
7391 if (BO->getLHS()->getType()->isDependentType() ||
7392 BO->getRHS()->getType()->isDependentType()) {
7393 if (BO->getOpcode() != BO_Assign)
7394 return;
7395 } else if (!BO->isAssignmentOp())
7396 return;
7397 else
7398 IsCompoundAssign = BO->isCompoundAssignmentOp();
7399 LHS = dyn_cast(BO->getLHS());
7400 } else if (CXXOperatorCallExpr *COCE = dyn_cast(E)) {
7401 if (COCE->getOperator() != OO_Equal)
7402 return;
7403 LHS = dyn_cast(COCE->getArg(0));
7404 } else if (UnaryOperator *UO = dyn_cast(E)) {
7405 if (!UO->isIncrementDecrementOp())
7406 return;
7407 isIncrementDecrementUnaryOp = true;
7408 LHS = dyn_cast(UO->getSubExpr());
7409 }
7410 if (!LHS)
7411 return;
7413 if (!VD)
7414 return;
7415
7416
7417
7418 if ((IsCompoundAssign || isIncrementDecrementUnaryOp) &&
7420 return;
7423 return;
7424 iter->getSecond()--;
7425}
7426
7427
7428
7431
7434 if (result.isInvalid()) return E;
7435 E = result.get();
7436 }
7437
7439
7440
7441
7442
7446 return E;
7447 E = Res.get();
7448 } else {
7449
7450
7452 }
7453
7454
7455
7456
7457
7458
7459
7460
7461
7466 return E;
7467 E = Res.get();
7468 }
7469 return E;
7470 }
7471
7472
7473
7474
7475
7477
7478
7479
7480
7483
7484 return E;
7485 }
7486
7487
7489
7491 return E;
7492 }
7493
7496 return E;
7497 E = Res.get();
7498
7501 diag::err_incomplete_type);
7502 return E;
7503}
7504
7506
7507
7509
7510 return E;
7511}
7512
7513
7514
7515
7516
7517
7518
7519
7520
7521
7522
7523
7524
7528 const VarDecl *DefVD = nullptr;
7529
7530
7533 return true;
7534 assert(DefVD);
7535 if (DefVD->isWeak())
7536 return false;
7537
7539
7540
7541
7542 return false;
7543 }
7544
7546}
7547
7548
7549
7550
7551
7552
7553
7554
7557
7560#ifndef NDEBUG
7562 while (isa_and_nonnull(DC))
7564 assert(
7566 "The current call operator must be synchronized with Sema's CurContext");
7567#endif
7568
7570
7571
7572
7573
7575
7576
7577
7578
7579
7580
7581
7582
7583
7584
7585
7587 !IsFullExprInstantiationDependent)
7588 return;
7589
7591 if (!UnderlyingVar)
7592 return;
7593
7594
7595
7600 const bool IsVarNeverAConstantExpression =
7602 if (!IsFullExprInstantiationDependent || IsVarNeverAConstantExpression) {
7603
7604
7605
7606
7607
7608
7609 QualType CaptureType, DeclRefType;
7613 false, CaptureType,
7614 DeclRefType, nullptr)) {
7615
7616
7619 true, CaptureType,
7620 DeclRefType, nullptr);
7621 }
7622 }
7623 });
7624
7625
7627
7628
7632 const unsigned FunctionScopeIndexOfCapturableLambda = *Index;
7634 false, true,
7635 &FunctionScopeIndexOfCapturableLambda);
7636 }
7637 }
7638
7639
7641}
7642
7644 bool DiscardedValue, bool IsConstexpr,
7645 bool IsTemplateArgument) {
7647
7650
7653
7654 if (DiscardedValue) {
7655
7656 if (getLangOpts().DebuggerCastResultToId &&
7661 }
7662
7666
7670
7672 }
7673
7676
7677 CheckCompletedExpr(FullExpr.get(), CC, IsConstexpr);
7678
7679
7680
7681
7682
7683
7684
7685
7686
7687
7688
7689
7690
7691
7692
7693
7694
7695
7696
7697
7698
7699
7700
7701
7702
7703
7704
7705
7706
7707
7708
7710 getCurLambda(true);
7711
7712
7713
7714
7715
7716
7717
7718
7719
7720
7721
7722
7723
7724
7726 while (isa_and_nonnull(DC))
7729 if (IsInLambdaDeclContext && CurrentLSI &&
7732 *this);
7734}
7735
7737 if (!FullStmt) return StmtError();
7738
7740}
7741
7746 if (!TargetName)
7748
7749
7752
7753
7758
7765
7768
7771 }
7772
7773 llvm_unreachable("Invalid LookupResult Kind!");
7774}
7775
7778 bool IsIfExists,
7782
7783
7788
7790}
7791
7797
7801 assert((( && TemplateId) || (TypeName && !TemplateId)) &&
7802 "Exactly one of TypeName and TemplateId must be specified.");
7808 &TSI, false);
7809 if (T.isNull())
7810 return nullptr;
7811 } else {
7820 if (T.isInvalid())
7821 return nullptr;
7823 return nullptr;
7824 }
7826}
7827
7833
7838
7839
7840
7841
7842
7843
7844
7845
7846
7847
7848
7849 auto &II = Context.Idents.get("expr-type");
7853 0, &II,
7854 true,
7855 false,
7856 true);
7857
7860 true))
7861
7863
7868 nullptr);
7870 E, false, NoexceptLoc,
7872}
7873
7888
7889
7890
7893 QualType MatchedType = Context.getReferenceQualifiedType(E);
7896
7898
7901 const TypeConstraint *TC = Param->getTypeConstraint();
7902 assert(TC && "Type Constraint cannot be null here");
7904 assert(IDC && "ImmediatelyDeclaredConstraint can't be null here.");
7906 bool HasError = Constraint.isInvalid();
7907 if (!HasError) {
7908 SubstitutedConstraintExpr =
7911 HasError = true;
7912 }
7913 if (HasError) {
7916 [&](llvm::raw_ostream &OS) {
7917 IDC->printPretty(OS, nullptr,
7918 getPrintingPolicy());
7919 }),
7920 IsSimple, NoexceptLoc, ReturnTypeRequirement);
7921 }
7922 if (!SubstitutedConstraintExpr->isSatisfied())
7924 }
7926 ReturnTypeRequirement, Status,
7927 SubstitutedConstraintExpr);
7928}
7929
7936 IsSimple, NoexceptLoc,
7937 ReturnTypeRequirement);
7938}
7939
7944
7950
7954
7960 {},
7962 return nullptr;
7964 Satisfaction);
7965}
7966
7971 InvalidConstraintEntity,
7973}
7974
7978 Scope *BodyScope) {
7979 assert(BodyScope);
7980
7982 RequiresKWLoc);
7983
7985
7986 for (ParmVarDecl *Param : LocalParameters) {
7987 if (Param->getType()->isVoidType()) {
7988 if (LocalParameters.size() > 1) {
7989 Diag(Param->getBeginLoc(), diag::err_void_only_param);
7990 Param->setType(Context.IntTy);
7991 } else if (Param->getIdentifier()) {
7992 Diag(Param->getBeginLoc(), diag::err_param_with_void_type);
7993 Param->setType(Context.IntTy);
7994 } else if (Param->getType().hasQualifiers()) {
7995 Diag(Param->getBeginLoc(), diag::err_void_param_qualified);
7996 }
7997 } else if (Param->hasDefaultArg()) {
7998
7999
8000
8001 Diag(Param->getDefaultArgRange().getBegin(),
8002 diag::err_requires_expr_local_parameter_default_argument);
8003
8004 } else if (Param->isExplicitObjectParameter()) {
8005
8006
8007
8008
8009
8010
8011
8012
8013
8014
8015 Diag(Param->getExplicitObjectParamThisLoc(),
8016 diag::err_requires_expr_explicit_object_parameter);
8017 Param->setExplicitObjectParameterLoc(SourceLocation());
8018 }
8019
8020 Param->setDeclContext(Body);
8021
8022 if (Param->getIdentifier()) {
8025 }
8026 }
8027 return Body;
8028}
8029
8031 assert(CurContext && "DeclContext imbalance!");
8033 assert(CurContext && "Popped translation unit!");
8034}
8035
8042 LocalParameters, RParenLoc, Requirements,
8043 ClosingBraceLoc);
8046 return RE;
8047}
Defines the clang::ASTContext interface.
This file provides some common utility functions for processing Lambda related AST Constructs.
Defines a function that returns the minimum OS versions supporting C++17's aligned allocation functio...
static bool CanThrow(Expr *E, ASTContext &Ctx)
static const char * getPlatformName(Darwin::DarwinPlatformKind Platform, Darwin::DarwinEnvironmentKind Environment)
Defines the C++ Decl subclasses, other than those for templates (found in DeclTemplate....
This file defines the classes used to store parsed information about declaration-specifiers and decla...
Defines the clang::Expr interface and subclasses for C++ expressions.
Defines Expressions and AST nodes for C++2a concepts.
llvm::MachO::Record Record
Implements a partial diagnostic that can be emitted anwyhere in a DiagnosticBuilder stream.
Defines the clang::Preprocessor interface.
@ NotForRedeclaration
The lookup is a reference to this name that is not for the purpose of redeclaring the name.
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.
static bool doesUsualArrayDeleteWantSize(Sema &S, SourceLocation loc, TypeAwareAllocationMode PassType, QualType allocType)
Determine whether a given type is a class for which 'delete[]' would call a member 'operator delete[]...
Definition SemaExprCXX.cpp:1979
static void collectPublicBases(CXXRecordDecl *RD, llvm::DenseMap< CXXRecordDecl *, unsigned > &SubobjectsSeen, llvm::SmallPtrSetImpl< CXXRecordDecl * > &VBases, llvm::SetVector< CXXRecordDecl * > &PublicSubobjectsSeen, bool ParentIsPublic)
Definition SemaExprCXX.cpp:917
static bool ConvertForConditional(Sema &Self, ExprResult &E, QualType T)
Perform an "extended" implicit conversion as returned by TryClassUnification.
Definition SemaExprCXX.cpp:5667
static void MaybeDecrementCount(Expr *E, llvm::DenseMap< const VarDecl *, int > &RefsMinusAssignments)
Definition SemaExprCXX.cpp:7385
static bool CheckDeleteOperator(Sema &S, SourceLocation StartLoc, SourceRange Range, bool Diagnose, CXXRecordDecl *NamingClass, DeclAccessPair Decl, FunctionDecl *Operator)
Definition SemaExprCXX.cpp:1908
static void DiagnoseMismatchedNewDelete(Sema &SemaRef, SourceLocation DeleteLoc, const MismatchingNewDeleteDetector &Detector)
Definition SemaExprCXX.cpp:3918
static void getUnambiguousPublicSubobjects(CXXRecordDecl *RD, llvm::SmallVectorImpl< CXXRecordDecl * > &Objects)
Definition SemaExprCXX.cpp:946
static bool isLegalArrayNewInitializer(CXXNewInitializationStyle Style, Expr *Init, bool IsCPlusPlus20)
Definition SemaExprCXX.cpp:2086
static QualType adjustVectorType(ASTContext &Context, QualType FromTy, QualType ToType, QualType *ElTy=nullptr)
Definition SemaExprCXX.cpp:4688
static void CheckIfAnyEnclosingLambdasMustCaptureAnyPotentialCaptures(Expr *const FE, LambdaScopeInfo *const CurrentLSI, Sema &S)
Check if the current lambda has any potential captures that must be captured by any of its enclosing ...
Definition SemaExprCXX.cpp:7555
static void getUuidAttrOfType(Sema &SemaRef, QualType QT, llvm::SmallSetVector< const UuidAttr *, 1 > &UuidAttrs)
Grabs __declspec(uuid()) off a type, or returns 0 if we cannot resolve to a single GUID.
Definition SemaExprCXX.cpp:701
DeallocLookupMode
Definition SemaExprCXX.cpp:2864
@ Untyped
Definition SemaExprCXX.cpp:2864
@ OptionallyTyped
Definition SemaExprCXX.cpp:2864
static QualType adjustCVQualifiersForCXXThisWithinLambda(ArrayRef< FunctionScopeInfo * > FunctionScopes, QualType ThisTy, DeclContext *CurSemaContext, ASTContext &ASTCtx)
Definition SemaExprCXX.cpp:1101
static bool resolveAllocationOverloadInterior(Sema &S, LookupResult &R, SourceRange Range, ResolveMode Mode, SmallVectorImpl< Expr * > &Args, AlignedAllocationMode &PassAlignment, FunctionDecl *&Operator, OverloadCandidateSet *AlignedCandidates, Expr *AlignArg, bool Diagnose)
Definition SemaExprCXX.cpp:2692
static bool FindConditionalOverload(Sema &Self, ExprResult &LHS, ExprResult &RHS, SourceLocation QuestionLoc)
Try to find a common type for two according to C++0x 5.16p5.
Definition SemaExprCXX.cpp:5608
static bool TryClassUnification(Sema &Self, Expr *From, Expr *To, SourceLocation QuestionLoc, bool &HaveConversion, QualType &ToType)
Try to convert a type to another according to C++11 5.16p3.
Definition SemaExprCXX.cpp:5518
static bool resolveAllocationOverload(Sema &S, LookupResult &R, SourceRange Range, SmallVectorImpl< Expr * > &Args, ImplicitAllocationParameters &IAP, FunctionDecl *&Operator, OverloadCandidateSet *AlignedCandidates, Expr *AlignArg, bool Diagnose)
Definition SemaExprCXX.cpp:2884
static UsualDeallocFnInfo resolveDeallocationOverload(Sema &S, LookupResult &R, const ImplicitDeallocationParameters &IDP, SourceLocation Loc, llvm::SmallVectorImpl< UsualDeallocFnInfo > *BestFns=nullptr)
Select the correct "usual" deallocation function to use from a selection of deallocation functions (e...
Definition SemaExprCXX.cpp:1937
static bool hasNewExtendedAlignment(Sema &S, QualType AllocType)
Determine whether a type has new-extended alignment.
Definition SemaExprCXX.cpp:1902
static ExprResult BuildCXXCastArgument(Sema &S, SourceLocation CastLoc, QualType Ty, CastKind Kind, CXXMethodDecl *Method, DeclAccessPair FoundDecl, bool HadMultipleCandidates, Expr *From)
Definition SemaExprCXX.cpp:4524
ResolveMode
Definition SemaExprCXX.cpp:2691
@ Untyped
Definition SemaExprCXX.cpp:2691
@ Typed
Definition SemaExprCXX.cpp:2691
static bool VariableCanNeverBeAConstantExpression(VarDecl *Var, ASTContext &Context)
Definition SemaExprCXX.cpp:7525
static bool canRecoverDotPseudoDestructorCallsOnPointerObjects(Sema &SemaRef, QualType DestructedType)
Check if it's ok to try and recover dot pseudo destructor calls on pointer objects.
Definition SemaExprCXX.cpp:7035
static bool CheckArrow(Sema &S, QualType &ObjectType, Expr *&Base, tok::TokenKind &OpKind, SourceLocation OpLoc)
Definition SemaExprCXX.cpp:6987
static bool resolveBuiltinNewDeleteOverload(Sema &S, CallExpr *TheCall, bool IsDelete, FunctionDecl *&Operator)
Definition SemaExprCXX.cpp:4232
static bool isValidVectorForConditionalCondition(ASTContext &Ctx, QualType CondTy)
Definition SemaExprCXX.cpp:5683
static void LookupGlobalDeallocationFunctions(Sema &S, SourceLocation Loc, LookupResult &FoundDelete, DeallocLookupMode Mode, DeclarationName Name)
Definition SemaExprCXX.cpp:2866
static void noteOperatorArrows(Sema &S, ArrayRef< FunctionDecl * > OperatorArrows)
Note a set of 'operator->' functions that were used for a member access.
Definition SemaExprCXX.cpp:6818
static void buildLambdaThisCaptureFixit(Sema &Sema, LambdaScopeInfo *LSI)
Definition SemaExprCXX.cpp:1274
static bool isNonPlacementDeallocationFunction(Sema &S, FunctionDecl *FD)
Determine whether the given function is a non-placement deallocation function.
Definition SemaExprCXX.cpp:1725
This file declares semantic analysis for HLSL constructs.
This file provides some common utility functions for processing Lambdas.
This file declares semantic analysis for Objective-C.
This file declares semantic analysis functions specific to PowerPC.
static QualType getPointeeType(const MemRegion *R)
Defines the clang::TokenKind enum and support functions.
Defines the clang::TypeLoc interface and its subclasses.
C Language Family Type Representation.
a trap message and trap category.
Holds long-lived AST nodes (such as types and decls) that can be referred to throughout the semantic ...
TranslationUnitDecl * getTranslationUnitDecl() const
DeclarationNameTable DeclarationNames
QualType getPointerType(QualType T) const
Return the uniqued reference to the type for a pointer to the specified type.
QualType getConstantArrayType(QualType EltTy, const llvm::APInt &ArySize, const Expr *SizeExpr, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return the unique reference to the type for a constant array of the specified element type.
const LangOptions & getLangOpts() const
QualType getBaseElementType(const ArrayType *VAT) const
Return the innermost element type of an array type.
QualType getQualifiedType(SplitQualType split) const
Un-split a SplitQualType.
QualType getObjCObjectPointerType(QualType OIT) const
Return a ObjCObjectPointerType type for the given ObjCObjectType.
unsigned getTypeAlignIfKnown(QualType T, bool NeedsPreferredAlignment=false) const
Return the alignment of a type, in bits, or 0 if the type is incomplete and we cannot determine the a...
QualType getMemberPointerType(QualType T, NestedNameSpecifier Qualifier, const CXXRecordDecl *Cls) const
Return the uniqued reference to the type for a member pointer to the specified type in the specified ...
QualType getSizeType() const
Return the unique type for "size_t" (C99 7.17), defined in <stddef.h>.
const TargetInfo & getTargetInfo() const
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.
QualType getIncompleteArrayType(QualType EltTy, ArraySizeModifier ASM, unsigned IndexTypeQuals) const
Return a unique reference to the type for an incomplete array of the specified element type.
Represents a constant array type that does not decay to a pointer when used as a function parameter.
QualType getConstantArrayType(const ASTContext &Ctx) const
Represents an array type, per C99 6.7.5.2 - Array Declarators.
QualType getElementType() const
QualType getValueType() const
Gets the type contained by this atomic type, i.e.
Attr - This represents one attribute.
A builtin binary operation expression such as "x + y" or "x <= y".
static BinaryOperator * Create(const ASTContext &C, Expr *lhs, Expr *rhs, Opcode opc, QualType ResTy, ExprValueKind VK, ExprObjectKind OK, SourceLocation opLoc, FPOptionsOverride FPFeatures)
This class is used for builtin types like 'int'.
Represents a base class of a C++ class.
Represents binding an expression to a temporary.
static CXXBindTemporaryExpr * Create(const ASTContext &C, CXXTemporary *Temp, Expr *SubExpr)
const Expr * getSubExpr() const
A boolean literal, per ([C++ lex.bool] Boolean literals).
Represents a call to a C++ constructor.
Represents a C++ constructor within a class.
Represents a C++ conversion function within a class.
FieldDecl * getMember() const
If this is a member initializer, returns the declaration of the non-static data member being initiali...
Expr * getInit() const
Get the initializer.
Represents a delete expression for memory deallocation and destructor calls, e.g.
SourceLocation getBeginLoc() const
Represents a C++ destructor within a class.
static CXXFunctionalCastExpr * Create(const ASTContext &Context, QualType T, ExprValueKind VK, TypeSourceInfo *Written, CastKind Kind, Expr *Op, const CXXCastPath *Path, FPOptionsOverride FPO, SourceLocation LPLoc, SourceLocation RPLoc)
Represents a static or instance method of a struct/union/class.
const CXXRecordDecl * getParent() const
Return the parent of this method declaration, which is the class in which this method is defined.
QualType getFunctionObjectParameterType() const
static CXXNewExpr * Create(const ASTContext &Ctx, bool IsGlobalNew, FunctionDecl *OperatorNew, FunctionDecl *OperatorDelete, const ImplicitAllocationParameters &IAP, bool UsualArrayDeleteWantsSize, ArrayRef< Expr * > PlacementArgs, SourceRange TypeIdParens, std::optional< Expr * > ArraySize, CXXNewInitializationStyle InitializationStyle, Expr *Initializer, QualType Ty, TypeSourceInfo *AllocatedTypeInfo, SourceRange Range, SourceRange DirectInitRange)
Create a c++ new expression.
Represents a C++11 noexcept expression (C++ [expr.unary.noexcept]).
The null pointer literal (C++11 [lex.nullptr])
A call to an overloaded operator written using operator syntax.
Represents a C++ pseudo-destructor (C++ [expr.pseudo]).
Represents a C++ struct/union/class.
static CXXRecordDecl * Create(const ASTContext &C, TagKind TK, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, CXXRecordDecl *PrevDecl=nullptr)
bool isPolymorphic() const
Whether this class is polymorphic (C++ [class.virtual]), which means that the class contains or inher...
capture_const_range captures() const
bool isAbstract() const
Determine whether this class has a pure virtual function.
bool hasIrrelevantDestructor() const
Determine whether this class has a destructor which has no semantic effect.
bool hasDefinition() const
CXXDestructorDecl * getDestructor() const
Returns the destructor decl for this class.
CXXMethodDecl * getLambdaCallOperator() const
Retrieve the lambda call operator of the closure type if this is a closure type.
An expression "T()" which creates an rvalue of a non-class type T.
Represents a C++ nested-name-specifier or a global scope specifier.
bool isNotEmpty() const
A scope specifier is present, but may be valid or invalid.
SourceLocation getLastQualifierNameLoc() const
Retrieve the location of the name in the last qualifier in this nested name specifier.
SourceLocation getEndLoc() const
SourceRange getRange() const
bool isSet() const
Deprecated.
NestedNameSpecifier getScopeRep() const
Retrieve the representation of the nested-name-specifier.
NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const
Retrieve a nested-name-specifier with location information, copied into the given AST context.
bool isInvalid() const
An error occurred during parsing of the scope specifier.
void Adopt(NestedNameSpecifierLoc Other)
Adopt an existing nested-name-specifier (with source-range information).
Represents a C++ temporary.
void setDestructor(const CXXDestructorDecl *Dtor)
static CXXTemporary * Create(const ASTContext &C, const CXXDestructorDecl *Destructor)
Represents the this expression in C++.
static CXXThisExpr * Create(const ASTContext &Ctx, SourceLocation L, QualType Ty, bool IsImplicit)
A C++ throw-expression (C++ [except.throw]).
A C++ typeid expression (C++ [expr.typeid]), which gets the type_info that corresponds to the supplie...
static CXXUnresolvedConstructExpr * Create(const ASTContext &Context, QualType T, TypeSourceInfo *TSI, SourceLocation LParenLoc, ArrayRef< Expr * > Args, SourceLocation RParenLoc, bool IsListInit)
A Microsoft C++ __uuidof expression, which gets the _GUID that corresponds to the supplied type or ex...
CallExpr - Represents a function call (C99 6.5.2.2, C++ [expr.call]).
Expr * getArg(unsigned Arg)
getArg - Return the specified argument.
SourceLocation getBeginLoc() const
void setArg(unsigned Arg, Expr *ArgExpr)
setArg - Set the specified argument.
unsigned getNumArgs() const
getNumArgs - Return the number of actual arguments to this call.
CharUnits - This is an opaque type for sizes expressed in character units.
QuantityType getQuantity() const
getQuantity - Get the raw integer representation of this quantity.
Declaration of a class template.
Complex values, per C99 6.2.5p11.
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)
Represents the specialization of a concept - evaluates to a prvalue of type bool.
bool isSatisfied() const
Whether or not the concept with the given arguments was satisfied when the expression was created.
const ASTConstraintSatisfaction & getSatisfaction() const
Get elaborated satisfaction info about the template arguments' satisfaction of the named concept.
Represents the canonical version of C arrays with a specified constant size.
static unsigned getNumAddressingBits(const ASTContext &Context, QualType ElementType, const llvm::APInt &NumElements)
Determine the number of bits required to address a member of.
static unsigned getMaxSizeBits(const ASTContext &Context)
Determine the maximum number of active bits that an array's size can require, which limits the maximu...
Represents a concrete matrix type with constant number of rows and columns.
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
A POD class for pairing a NamedDecl* with an access specifier.
static DeclAccessPair make(NamedDecl *D, AccessSpecifier AS)
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.
lookup_result::iterator lookup_iterator
DeclContextLookupResult lookup_result
bool isDependentContext() const
Determines whether this context is dependent on a template parameter.
lookup_result lookup(DeclarationName Name) const
lookup - Find the declarations (if any) with the given Name in this context.
A reference to a declared variable, function, enum, etc.
Captures information about "declaration specifiers".
bool hasAutoTypeSpec() const
Expr * getPackIndexingExpr() const
TST getTypeSpecType() const
SourceLocation getBeginLoc() const LLVM_READONLY
static const TST TST_typename_pack_indexing
ParsedType getRepAsType() const
SourceLocation getEllipsisLoc() const
Expr * getRepAsExpr() const
static const TST TST_decltype
SourceLocation getTypeSpecTypeLoc() const
static const TST TST_decltype_auto
static const TST TST_error
SourceRange getTypeofParensRange() const
Decl - This represents one declaration (or definition), e.g.
bool isImplicit() const
isImplicit - Indicates whether the declaration was implicitly generated by the implementation.
void setInvalidDecl(bool Invalid=true)
setInvalidDecl - Indicates the Decl had a semantic error.
FunctionDecl * getAsFunction() LLVM_READONLY
Returns the function itself, or the templated function if this is a function template.
bool isInvalidDecl() const
SourceLocation getLocation() const
void setLocalOwningModule(Module *M)
void setImplicit(bool I=true)
DeclContext * getDeclContext()
@ ReachableWhenImported
This declaration has an owning module, and is visible to lookups that occurs within that module.
void setModuleOwnershipKind(ModuleOwnershipKind MOK)
Set whether this declaration is hidden from name lookup.
The name of a declaration.
bool isDependentName() const
Determines whether the name itself is dependent, e.g., because it involves a C++ type that is itself ...
bool isAnyOperatorDelete() const
OverloadedOperatorKind getCXXOverloadedOperator() const
If this name is the name of an overloadable operator in C++ (e.g., operator+), retrieve the kind of o...
bool isAnyOperatorNew() const
SourceLocation getBeginLoc() const LLVM_READONLY
Information about one declarator, including the parsed type information and the identifier.
const DeclaratorChunk & getTypeObject(unsigned i) const
Return the specified TypeInfo from this declarator.
const DeclSpec & getDeclSpec() const
getDeclSpec - Return the declaration-specifier that this declarator was declared with.
SourceLocation getEndLoc() const LLVM_READONLY
void DropFirstTypeObject()
unsigned getNumTypeObjects() const
Return the number of types applied to this declarator.
bool isInvalidType() const
SourceRange getSourceRange() const LLVM_READONLY
Get the source range that spans this declarator.
void setRParenLoc(SourceLocation Loc)
void setDecltypeLoc(SourceLocation Loc)
A little helper class (which is basically a smart pointer that forwards info from DiagnosticsEngine a...
DiagnosticOptions & getDiagnosticOptions() const
Retrieve the diagnostic options.
bool isComplete() const
Returns true if this can be considered a complete type.
static EnumDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl, bool IsScoped, bool IsScopedUsingClassTag, bool IsFixed)
bool isFixed() const
Returns true if this is an Objective-C, C++11, or Microsoft-style enumeration with a fixed underlying...
static ExprWithCleanups * Create(const ASTContext &C, EmptyShell empty, unsigned numObjects)
This represents one expression.
bool isReadIfDiscardedInCPlusPlus11() const
Determine whether an lvalue-to-rvalue conversion should implicitly be applied to this expression if i...
bool isValueDependent() const
Determines whether the value of this expression depends on.
ExprValueKind getValueKind() const
getValueKind - The value kind that this expression produces.
bool refersToVectorElement() const
Returns whether this expression refers to a vector element.
bool isTypeDependent() const
Determines whether the type of this expression depends on.
Expr * IgnoreParenImpCasts() LLVM_READONLY
Skip past any parentheses and implicit casts which might surround this expression until reaching a fi...
Expr * IgnoreParens() LLVM_READONLY
Skip past any parentheses which might surround this expression until reaching a fixed point.
static bool hasAnyTypeDependentArguments(ArrayRef< Expr * > Exprs)
hasAnyTypeDependentArguments - Determines if any of the expressions in Exprs is type-dependent.
@ NPC_ValueDependentIsNull
Specifies that a value-dependent expression of integral or dependent type should be considered a null...
ExprObjectKind getObjectKind() const
getObjectKind - The object kind that this expression produces.
bool HasSideEffects(const ASTContext &Ctx, bool IncludePossibleEffects=true) const
HasSideEffects - This routine returns true for all those expressions which have any effect other than...
bool isInstantiationDependent() const
Whether this expression is instantiation-dependent, meaning that it depends in some way on.
NullPointerConstantKind isNullPointerConstant(ASTContext &Ctx, NullPointerConstantValueDependence NPC) const
isNullPointerConstant - C99 6.3.2.3p3 - Test if this reduces down to a Null pointer constant.
SourceLocation getExprLoc() const LLVM_READONLY
getExprLoc - Return the preferred location for the arrow when diagnosing a problem with a generic exp...
bool refersToBitField() const
Returns true if this expression is a gl-value that potentially refers to a bit-field.
Classification Classify(ASTContext &Ctx) const
Classify - Classify this expression according to the C++11 expression taxonomy.
bool isOrdinaryOrBitFieldObject() const
bool hasPlaceholderType() const
Returns whether this expression has a placeholder type.
static ExprValueKind getValueKindForType(QualType T)
getValueKindForType - Given a formal return or parameter type, give its value kind.
Represents difference between two FPOptions values.
Annotates a diagnostic with some code that should be inserted, removed, or replaced to fix the proble...
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.
FullExpr - Represents a "full-expression" node.
Represents a function declaration or definition.
static constexpr unsigned RequiredTypeAwareDeleteParameterCount
Count of mandatory parameters for type aware operator delete.
static FunctionDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation NLoc, DeclarationName N, QualType T, TypeSourceInfo *TInfo, StorageClass SC, bool UsesFPIntrin=false, bool isInlineSpecified=false, bool hasWrittenPrototype=true, ConstexprSpecKind ConstexprKind=ConstexprSpecKind::Unspecified, const AssociatedConstraint &TrailingRequiresClause={})
const ParmVarDecl * getParamDecl(unsigned i) const
bool isFunctionTemplateSpecialization() const
Determine whether this function is a function template specialization.
bool isThisDeclarationADefinition() const
Returns whether this specific declaration of the function is also a definition that does not contain ...
StringLiteral * getDeletedMessage() const
Get the message that indicates why this function was deleted.
QualType getReturnType() const
bool isTrivial() const
Whether this function is "trivial" in some specialized C++ senses.
bool isReplaceableGlobalAllocationFunction(UnsignedOrNone *AlignmentParam=nullptr, bool *IsNothrow=nullptr) const
Determines whether this function is one of the replaceable global allocation functions: void *operato...
bool isDeleted() const
Whether this function has been deleted.
bool isTypeAwareOperatorNewOrDelete() const
Determine whether this is a type aware operator new or delete.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
unsigned getNumParams() const
Return the number of parameters this function must have based on its FunctionType.
bool isDefined(const FunctionDecl *&Definition, bool CheckForPendingFriendDefinition=false) const
Returns true if the function has a definition that does not need to be instantiated.
Represents a prototype with parameter type info, e.g.
QualType getParamType(unsigned i) const
Declaration of a template function.
ExtInfo withCallingConv(CallingConv cc) const
ExtInfo withNoReturn(bool noReturn) const
FunctionType - C99 6.7.5.3 - Function Declarators.
One of these records is kept for each identifier that is lexed.
ReservedIdentifierStatus isReserved(const LangOptions &LangOpts) const
Determine whether this is a name reserved for the implementation (C99 7.1.3, C++ [lib....
ReservedLiteralSuffixIdStatus isReservedLiteralSuffixId() const
Determine whether this is a name reserved for future standardization or the implementation (C++ [usrl...
StringRef getName() const
Return the actual identifier string.
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)
ImplicitConversionSequence - Represents an implicit conversion sequence, which may be a standard conv...
@ StaticObjectArgumentConversion
StandardConversionSequence Standard
When ConversionKind == StandardConversion, provides the details of the standard conversion sequence.
UserDefinedConversionSequence UserDefined
When ConversionKind == UserDefinedConversion, provides the details of the user-defined conversion seq...
void DiagnoseAmbiguousConversion(Sema &S, SourceLocation CaretLoc, const PartialDiagnostic &PDiag) const
Diagnoses an ambiguous conversion.
Describes the kind of initialization being performed, along with location information for tokens rela...
static InitializationKind CreateDefault(SourceLocation InitLoc)
Create a default initialization.
static InitializationKind CreateDirect(SourceLocation InitLoc, SourceLocation LParenLoc, SourceLocation RParenLoc)
Create a direct initialization.
static InitializationKind CreateCopy(SourceLocation InitLoc, SourceLocation EqualLoc, bool AllowExplicitConvs=false)
Create a copy initialization.
static InitializationKind CreateDirectList(SourceLocation InitLoc)
static InitializationKind CreateValue(SourceLocation InitLoc, SourceLocation LParenLoc, SourceLocation RParenLoc, bool isImplicit=false)
Create a value initialization.
Describes the sequence of initializations required to initialize a given object or reference with a s...
ExprResult Perform(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Args, QualType *ResultType=nullptr)
Perform the actual initialization of the given entity based on the computed initialization sequence.
bool isAmbiguous() const
Determine whether this initialization failed due to an ambiguity.
bool Diagnose(Sema &S, const InitializedEntity &Entity, const InitializationKind &Kind, ArrayRef< Expr * > Args)
Diagnose an potentially-invalid initialization sequence.
bool Failed() const
Determine whether the initialization sequence is invalid.
bool isDirectReferenceBinding() const
Determine whether this initialization is a direct reference binding (C++ [dcl.init....
Describes an entity that is being initialized.
static InitializedEntity InitializeException(SourceLocation ThrowLoc, QualType Type)
Create the initialization entity for an exception object.
static InitializedEntity InitializeTemporary(QualType Type)
Create the initialization entity for a temporary.
static InitializedEntity InitializeNew(SourceLocation NewLoc, QualType Type)
Create the initialization entity for an object allocated via new.
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'.
static SourceLocation findLocationAfterToken(SourceLocation loc, tok::TokenKind TKind, const SourceManager &SM, const LangOptions &LangOpts, bool SkipTrailingWhitespaceAndNewLine)
Checks that the given token is the first token that occurs after the given location (this excludes co...
A class for iterating through a result set and possibly filtering out results.
void erase()
Erase the last element returned from this iterator.
Represents the results of name lookup.
LLVM_ATTRIBUTE_REINITIALIZES void clear()
Clears out any current state.
DeclClass * getAsSingle() const
void setLookupName(DeclarationName Name)
Sets the name to look up.
bool empty() const
Return true if no decls were found.
SourceLocation getNameLoc() const
Gets the location of the identifier.
Filter makeFilter()
Create a filter for this result set.
CXXRecordDecl * getNamingClass() const
Returns the 'naming class' for this lookup, i.e.
UnresolvedSetImpl::iterator iterator
bool isClassLookup() const
Returns whether these results arose from performing a lookup into a class.
LookupResultKind getResultKind() const
void suppressDiagnostics()
Suppress the diagnostics that would normally fire because of this lookup.
DeclarationName getLookupName() const
Gets the name to look up.
MemberExpr - [C99 6.5.2.3] Structure and Union Members.
ValueDecl * getMemberDecl() const
Retrieve the member declaration to which this expression refers.
A pointer to member type per C++ 8.3.3 - Pointers to members.
CXXRecordDecl * getMostRecentCXXRecordDecl() const
Note: this can trigger extra deserialization when external AST sources are used.
QualType getPointeeType() const
Data structure that captures multiple levels of template argument lists for use in template instantia...
void addOuterRetainedLevels(unsigned Num)
This represents a decl that may have a name.
NamedDecl * getUnderlyingDecl()
Looks through UsingDecls and ObjCCompatibleAliasDecls for the underlying named decl.
IdentifierInfo * getIdentifier() const
Get the identifier that names this declaration, if there is one.
DeclarationName getDeclName() const
Get the actual, stored name of the declaration, which may be a special name.
std::string getNameAsString() const
Get a human-readable name for the declaration, even if it is one of the special kinds of names (C++ c...
A C++ nested-name-specifier augmented with source location information.
NamespaceAndPrefixLoc getAsNamespaceAndPrefix() const
TypeLoc getAsTypeLoc() const
Represents a C++ nested name specifier, such as "\::std::vector::".
const Type * getAsType() const
@ MicrosoftSuper
Microsoft's '__super' specifier, stored as a CXXRecordDecl* of the class it appeared in.
@ Global
The global specifier '::'. There is no stored value.
@ Type
A type, stored as a Type*.
@ Namespace
A namespace-like entity, stored as a NamespaceBaseDecl*.
ObjCArrayLiteral - used for objective-c array containers; as in: @["Hello", NSApp,...
ObjCBoxedExpr - used for generalized expression boxing.
ObjCDictionaryLiteral - AST node to represent objective-c dictionary literals; as in:"name" : NSUserN...
An expression that sends a message to the given Objective-C object or class.
ObjCMethodDecl - Represents an instance or class method declaration.
ObjCMethodFamily getMethodFamily() const
Determines the family of this method.
Represents a pointer to an Objective C object.
QualType getPointeeType() const
Gets the type pointed to by this ObjC pointer.
static OpaquePtr getFromOpaquePtr(void *P)
static OpaquePtr make(QualType P)
OpaqueValueExpr - An expression referring to an opaque object of a fixed type and value class.
OverloadCandidateSet - A set of overload candidates, used in C++ overload resolution (C++ 13....
@ CSK_Normal
Normal lookup.
@ CSK_Operator
C++ [over.match.oper]: Lookup of operator function candidates in a call using operator syntax.
SmallVectorImpl< OverloadCandidate >::iterator iterator
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...
OverloadingResult BestViableFunction(Sema &S, SourceLocation Loc, OverloadCandidateSet::iterator &Best)
Find the best viable function on this overload set, if it exists.
SmallVector< OverloadCandidate *, 32 > CompleteCandidates(Sema &S, OverloadCandidateDisplayKind OCD, ArrayRef< Expr * > Args, SourceLocation OpLoc=SourceLocation(), llvm::function_ref< bool(OverloadCandidate &)> Filter=[](OverloadCandidate &) { return true;})
void setEllipsisLoc(SourceLocation Loc)
ParenExpr - This represents a parenthesized expression, e.g.
Represents a parameter to a function.
static ParmVarDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, const IdentifierInfo *Id, QualType T, TypeSourceInfo *TInfo, StorageClass S, Expr *DefArg)
bool isEquivalent(PointerAuthQualifier Other) const
PointerType - C99 6.7.5.1 - Pointer Declarators.
QualType getPointeeType() const
Stores the type being destroyed by a pseudo-destructor expression.
TypeSourceInfo * getTypeSourceInfo() const
A (possibly-)qualified type.
bool isVolatileQualified() const
Determine whether this type is volatile-qualified.
QualType getNonLValueExprType(const ASTContext &Context) const
Determine the type of a (typically non-lvalue) expression with the specified result type.
QualType withConst() const
void addConst()
Add the const type qualifier to this QualType.
bool isNull() const
Return true if this QualType doesn't point to a type yet.
const Type * getTypePtr() const
Retrieves a pointer to the underlying (unqualified) type.
LangAS getAddressSpace() const
Return the address space of this type.
Qualifiers getQualifiers() const
Retrieve the set of qualifiers applied to this type.
Qualifiers::ObjCLifetime getObjCLifetime() const
Returns lifetime attribute of this type.
void getAsStringInternal(std::string &Str, const PrintingPolicy &Policy) const
QualType getNonReferenceType() const
If Type is a reference type (e.g., const int&), returns the type that the reference refers to ("const...
QualType getCanonicalType() const
QualType getUnqualifiedType() const
Retrieve the unqualified variant of the given type, removing as little sugar as possible.
bool isWebAssemblyReferenceType() const
Returns true if it is a WebAssembly Reference Type.
bool isConstQualified() const
Determine whether this type is const-qualified.
DestructionKind isDestructedType() const
Returns a nonzero value if objects of this type require non-trivial work to clean up after.
unsigned getCVRQualifiers() const
Retrieve the set of CVR (const-volatile-restrict) qualifiers applied to this type.
static std::string getAsString(SplitQualType split, const PrintingPolicy &Policy)
bool isAtLeastAsQualifiedAs(QualType Other, const ASTContext &Ctx) const
Determine whether this type is at least as qualified as the other given type, requiring exact equalit...
The collection of all-type qualifiers we support.
void removeCVRQualifiers(unsigned mask)
@ OCL_None
There is no lifetime qualification on this type.
bool hasCVRQualifiers() const
bool hasUnaligned() const
unsigned getAddressSpaceAttributePrintValue() const
Get the address space attribute value to be printed by diagnostics.
static bool isAddressSpaceSupersetOf(LangAS A, LangAS B, const ASTContext &Ctx)
Returns true if address space A is equal to or a superset of B.
void setAddressSpace(LangAS space)
unsigned getCVRUQualifiers() const
PointerAuthQualifier getPointerAuth() const
void setObjCGCAttr(GC type)
ObjCLifetime getObjCLifetime() const
static Qualifiers fromCVRUMask(unsigned CVRU)
LangAS getAddressSpace() const
void setPointerAuth(PointerAuthQualifier Q)
void setObjCLifetime(ObjCLifetime type)
Represents a struct/union/class.
Represents the body of a requires-expression.
static RequiresExprBodyDecl * Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc)
static RequiresExpr * Create(ASTContext &C, SourceLocation RequiresKWLoc, RequiresExprBodyDecl *Body, SourceLocation LParenLoc, ArrayRef< ParmVarDecl * > LocalParameters, SourceLocation RParenLoc, ArrayRef< concepts::Requirement * > Requirements, SourceLocation RBraceLoc)
Scope - A scope is a transient data structure that is used while parsing the program.
unsigned getFlags() const
getFlags - Return the flags for this scope.
bool isDeclScope(const Decl *D) const
isDeclScope - Return true if this is the scope that the specified decl is declared in.
DeclContext * getEntity() const
Get the entity corresponding to this scope.
const Scope * getParent() const
getParent - Return the scope that this is nested in.
@ BlockScope
This is a scope that corresponds to a block/closure object.
@ ClassScope
The scope of a struct/union/class definition.
@ TryScope
This is the scope of a C++ try statement.
@ FnScope
This indicates that the scope corresponds to a function, which means that labels are set here.
@ ObjCMethodScope
This scope corresponds to an Objective-C method body.
A generic diagnostic builder for errors which may or may not be deferred.
PartialDiagnostic PDiag(unsigned DiagID=0)
Build a partial diagnostic.
SemaDiagnosticBuilder Diag(SourceLocation Loc, unsigned DiagID)
Emit a diagnostic.
CUDAFunctionTarget CurrentTarget()
Gets the CUDA target for the current context.
SemaDiagnosticBuilder DiagIfDeviceCode(SourceLocation Loc, unsigned DiagID)
Creates a SemaDiagnosticBuilder that emits the diagnostic if the current context is "used as device c...
void EraseUnwantedMatches(const FunctionDecl *Caller, llvm::SmallVectorImpl< std::pair< DeclAccessPair, FunctionDecl * > > &Matches)
Finds a function in Matches with highest calling priority from Caller context and erases all function...
CUDAFunctionPreference IdentifyPreference(const FunctionDecl *Caller, const FunctionDecl *Callee)
Identifies relative preference of a given Caller/Callee combination, based on their host/device attri...
QualType FindCompositeObjCPointerType(ExprResult &LHS, ExprResult &RHS, SourceLocation QuestionLoc)
FindCompositeObjCPointerType - Helper method to find composite type of two objective-c pointer types ...
void EmitRelatedResultTypeNote(const Expr *E)
If the given expression involves a message send to a method with a related result type,...
CastKind PrepareCastToObjCObjectPointer(ExprResult &E)
Prepare a conversion of the given expression to an ObjC object pointer type.
ARCConversionResult CheckObjCConversion(SourceRange castRange, QualType castType, Expr *&op, CheckedConversionKind CCK, bool Diagnose=true, bool DiagnoseCFAudited=false, BinaryOperatorKind Opc=BO_PtrMemD, bool IsReinterpretCast=false)
Checks for invalid conversions and casts between retainable pointers and other pointer kinds for ARC ...
bool CheckPPCMMAType(QualType Type, SourceLocation TypeLoc)
CXXThisScopeRAII(Sema &S, Decl *ContextDecl, Qualifiers CXXThisTypeQuals, bool Enabled=true)
Introduce a new scope where 'this' may be allowed (when enabled), using the given declaration (which ...
Definition SemaExprCXX.cpp:1239
~CXXThisScopeRAII()
Definition SemaExprCXX.cpp:1268
Abstract base class used to perform a contextual implicit conversion from an expression to any type p...
Sema - This implements semantic analysis and AST building for C.
void DeclareGlobalNewDelete()
DeclareGlobalNewDelete - Declare the global forms of operator new and delete.
Definition SemaExprCXX.cpp:3345
IfExistsResult CheckMicrosoftIfExistsSymbol(Scope *S, CXXScopeSpec &SS, const DeclarationNameInfo &TargetNameInfo)
Definition SemaExprCXX.cpp:7743
ParsedType CreateParsedType(QualType T, TypeSourceInfo *TInfo)
Package the given type and TSI into a ParsedType.
FunctionDecl * FindUsualDeallocationFunction(SourceLocation StartLoc, ImplicitDeallocationParameters, DeclarationName Name, bool Diagnose=true)
Definition SemaExprCXX.cpp:3602
ExprResult ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc, bool isType, void *TyOrExpr, SourceLocation RParenLoc)
ActOnCXXTypeid - Parse typeid( something ).
Definition SemaExprCXX.cpp:638
QualType getCurrentThisType()
Try to retrieve the type of the 'this' pointer.
Definition SemaExprCXX.cpp:1209
ExprResult ActOnCXXUuidof(SourceLocation OpLoc, SourceLocation LParenLoc, bool isType, void *TyOrExpr, SourceLocation RParenLoc)
ActOnCXXUuidof - Parse __uuidof( something ).
Definition SemaExprCXX.cpp:778
Scope * getCurScope() const
Retrieve the parser's current scope.
QualType CheckVectorConditionalTypes(ExprResult &Cond, ExprResult &LHS, ExprResult &RHS, SourceLocation QuestionLoc)
Definition SemaExprCXX.cpp:5696
bool checkArrayElementAlignment(QualType EltTy, SourceLocation Loc)
ExprResult IgnoredValueConversions(Expr *E)
IgnoredValueConversions - Given that an expression's result is syntactically ignored,...
Definition SemaExprCXX.cpp:7429
bool RequireCompleteSizedType(SourceLocation Loc, QualType T, unsigned DiagID, const Ts &...Args)
@ LookupOrdinaryName
Ordinary name lookup, which finds ordinary names (functions, variables, typedefs, etc....
@ LookupDestructorName
Look up a name following ~ in a destructor name.
@ LookupTagName
Tag name lookup, which finds the names of enums, classes, structs, and unions.
@ LookupAnyName
Look up any declaration with any name.
void DiagnoseSentinelCalls(const NamedDecl *D, SourceLocation Loc, ArrayRef< Expr * > Args)
DiagnoseSentinelCalls - This routine checks whether a call or message-send is to a declaration with t...
ExprResult ActOnNoexceptExpr(SourceLocation KeyLoc, SourceLocation LParen, Expr *Operand, SourceLocation RParen)
Definition SemaExprCXX.cpp:7380
bool BuildTypeConstraint(const CXXScopeSpec &SS, TemplateIdAnnotation *TypeConstraint, TemplateTypeParmDecl *ConstrainedParameter, SourceLocation EllipsisLoc, bool AllowUnexpandedPack)
bool FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD, DeclarationName Name, FunctionDecl *&Operator, ImplicitDeallocationParameters, bool Diagnose=true)
Definition SemaExprCXX.cpp:3654
bool CheckCXXThisType(SourceLocation Loc, QualType Type)
Check whether the type of 'this' is valid in the current context.
Definition SemaExprCXX.cpp:1411
QualType UsualArithmeticConversions(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, ArithConvKind ACK)
UsualArithmeticConversions - Performs various conversions that are common to binary operators (C99 6....
QualType tryBuildStdTypeIdentity(QualType Type, SourceLocation Loc)
Looks for the std::type_identity template and instantiates it with Type, or returns a null type if ty...
bool CompleteConstructorCall(CXXConstructorDecl *Constructor, QualType DeclInitType, MultiExprArg ArgsPtr, SourceLocation Loc, SmallVectorImpl< Expr * > &ConvertedArgs, bool AllowExplicit=false, bool IsListInitialization=false)
Given a constructor and the set of arguments provided for the constructor, convert the arguments and ...
ExprResult CheckBooleanCondition(SourceLocation Loc, Expr *E, bool IsConstexpr=false)
CheckBooleanCondition - Diagnose problems involving the use of the given expression as a boolean cond...
@ Boolean
A boolean condition, from 'if', 'while', 'for', or 'do'.
@ Switch
An integral condition for a 'switch' statement.
@ ConstexprIf
A constant boolean condition from 'if constexpr'.
bool RequireCompleteDeclContext(CXXScopeSpec &SS, DeclContext *DC)
Require that the context specified by SS be complete.
bool GatherArgumentsForCall(SourceLocation CallLoc, FunctionDecl *FDecl, const FunctionProtoType *Proto, unsigned FirstParam, ArrayRef< Expr * > Args, SmallVectorImpl< Expr * > &AllArgs, VariadicCallType CallType=VariadicCallType::DoesNotApply, bool AllowExplicit=false, bool IsListInitialization=false)
GatherArgumentsForCall - Collector argument expressions for various form of call prototypes.
SmallVector< sema::FunctionScopeInfo *, 4 > FunctionScopes
Stack containing information about each of the nested function, block, and method scopes that are cur...
@ Ref_Compatible
Ref_Compatible - The two types are reference-compatible.
ExprResult BuildCXXFunctionalCastExpr(TypeSourceInfo *TInfo, QualType Type, SourceLocation LParenLoc, Expr *CastExpr, SourceLocation RParenLoc)
bool CheckCXXThisCapture(SourceLocation Loc, bool Explicit=false, bool BuildAndDiagnose=true, const unsigned *const FunctionScopeIndexToStopAt=nullptr, bool ByCopy=false)
Make sure the value of 'this' is actually available in the current context, if it is a potentially ev...
Definition SemaExprCXX.cpp:1286
ExprResult MaybeBindToTemporary(Expr *E)
MaybeBindToTemporary - If the passed in expression has a record type with a non-trivial destructor,...
Definition SemaExprCXX.cpp:6496
void MarkCaptureUsedInEnclosingContext(ValueDecl *Capture, SourceLocation Loc, unsigned CapturingScopeIndex)
ExprResult ActOnStartCXXMemberReference(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, ParsedType &ObjectType, bool &MayBePseudoDestructor)
Definition SemaExprCXX.cpp:6843
QualType CheckVectorOperands(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign, bool AllowBothBool, bool AllowBoolConversion, bool AllowBoolOperation, bool ReportInvalid)
type checking for vector binary operators.
concepts::Requirement * ActOnSimpleRequirement(Expr *E)
Definition SemaExprCXX.cpp:7792
FPOptionsOverride CurFPFeatureOverrides()
concepts::Requirement * ActOnCompoundRequirement(Expr *E, SourceLocation NoexceptLoc)
Definition SemaExprCXX.cpp:7829
ExprResult BuildOverloadedArrowExpr(Scope *S, Expr *Base, SourceLocation OpLoc, bool *NoArrowOperatorFound=nullptr)
BuildOverloadedArrowExpr - Build a call to an overloaded operator-> (if one exists),...
FunctionDecl * FindDeallocationFunctionForDestructor(SourceLocation StartLoc, CXXRecordDecl *RD, bool Diagnose, bool LookForGlobal, DeclarationName Name)
Definition SemaExprCXX.cpp:3628
concepts::Requirement::SubstitutionDiagnostic * createSubstDiagAt(SourceLocation Location, EntityPrinter Printer)
create a Requirement::SubstitutionDiagnostic with only a SubstitutedEntity and DiagLoc using ASTConte...
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 CheckUnevaluatedOperand(Expr *E)
Definition SemaExprCXX.cpp:7505
ExprResult ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal, bool ArrayForm, Expr *Operand)
ActOnCXXDelete - Parsed a C++ 'delete' expression (C++ 5.3.5), as in:
Definition SemaExprCXX.cpp:3977
void DiagnoseExceptionUse(SourceLocation Loc, bool IsTry)
ExprResult CheckSwitchCondition(SourceLocation SwitchLoc, Expr *Cond)
void diagnoseNullableToNonnullConversion(QualType DstType, QualType SrcType, SourceLocation Loc)
Warn if we're implicitly casting from a _Nullable pointer type to a _Nonnull one.
ExprResult ActOnCXXNullPtrLiteral(SourceLocation Loc)
ActOnCXXNullPtrLiteral - Parse 'nullptr'.
Definition SemaExprCXX.cpp:810
ExprResult BuildCXXTypeId(QualType TypeInfoType, SourceLocation TypeidLoc, TypeSourceInfo *Operand, SourceLocation RParenLoc)
Build a C++ typeid expression with a type operand.
Definition SemaExprCXX.cpp:535
ExprResult SubstExpr(Expr *E, const MultiLevelTemplateArgumentList &TemplateArgs)
DiagnosticsEngine & getDiagnostics() const
ExprResult MaybeConvertParenListExprToParenExpr(Scope *S, Expr *ME)
This is not an AltiVec-style cast or or C++ direct-initialization, so turn the ParenListExpr into a s...
concepts::TypeRequirement * BuildTypeRequirement(TypeSourceInfo *Type)
Definition SemaExprCXX.cpp:7941
AccessResult CheckDestructorAccess(SourceLocation Loc, CXXDestructorDecl *Dtor, const PartialDiagnostic &PDiag, QualType objectType=QualType())
bool isStdTypeIdentity(QualType Ty, QualType *TypeArgument, const Decl **MalformedDecl=nullptr)
Tests whether Ty is an instance of std::type_identity and, if it is and TypeArgument is not NULL,...
FunctionDecl * ResolveAddressOfOverloadedFunction(Expr *AddressOfExpr, QualType TargetType, bool Complain, DeclAccessPair &Found, bool *pHadMultipleCandidates=nullptr)
ResolveAddressOfOverloadedFunction - Try to resolve the address of an overloaded function (C++ [over....
void PushOnScopeChains(NamedDecl *D, Scope *S, bool AddToContext=true)
Add this decl to the scope shadowed decl chains.
ParsedType getDestructorName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec &SS, ParsedType ObjectType, bool EnteringContext)
Definition SemaExprCXX.cpp:119
void CleanupVarDeclMarking()
ExprResult DefaultFunctionArrayLvalueConversion(Expr *E, bool Diagnose=true)
ASTContext & getASTContext() const
void DeclareGlobalAllocationFunction(DeclarationName Name, QualType Return, ArrayRef< QualType > Params)
DeclareGlobalAllocationFunction - Declares a single implicit global allocation function if it doesn't...
Definition SemaExprCXX.cpp:3476
bool DiagnoseUnexpandedParameterPackInRequiresExpr(RequiresExpr *RE)
If the given requirees-expression contains an unexpanded reference to one of its own parameter packs,...
CXXDestructorDecl * LookupDestructor(CXXRecordDecl *Class)
Look for the destructor of the given class.
bool tryCaptureVariable(ValueDecl *Var, SourceLocation Loc, TryCaptureKind Kind, SourceLocation EllipsisLoc, bool BuildAndDiagnose, QualType &CaptureType, QualType &DeclRefType, const unsigned *const FunctionScopeIndexToStopAt)
Try to capture the given variable.
NamespaceDecl * getOrCreateStdNamespace()
Retrieve the special "std" namespace, which may require us to implicitly define the namespace.
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.
ExprResult ActOnPseudoDestructorExpr(Scope *S, Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, CXXScopeSpec &SS, UnqualifiedId &FirstTypeName, SourceLocation CCLoc, SourceLocation TildeLoc, UnqualifiedId &SecondTypeName)
Definition SemaExprCXX.cpp:7169
bool CheckArgsForPlaceholders(MultiExprArg args)
Check an argument list for placeholders that we won't try to handle later.
AccessResult CheckAllocationAccess(SourceLocation OperatorLoc, SourceRange PlacementRange, CXXRecordDecl *NamingClass, DeclAccessPair FoundDecl, bool Diagnose=true)
Checks access to an overloaded operator new or delete.
AccessResult CheckMemberOperatorAccess(SourceLocation Loc, Expr *ObjectExpr, const SourceRange &, DeclAccessPair FoundDecl)
void ActOnFinishRequiresExpr()
Definition SemaExprCXX.cpp:8030
ExprResult BuildCXXNew(SourceRange Range, bool UseGlobal, SourceLocation PlacementLParen, MultiExprArg PlacementArgs, SourceLocation PlacementRParen, SourceRange TypeIdParens, QualType AllocType, TypeSourceInfo *AllocTypeInfo, std::optional< Expr * > ArraySize, SourceRange DirectInitRange, Expr *Initializer)
Definition SemaExprCXX.cpp:2136
void DiagnoseUseOfDeletedFunction(SourceLocation Loc, SourceRange Range, DeclarationName Name, OverloadCandidateSet &CandidateSet, FunctionDecl *Fn, MultiExprArg Args, bool IsMember=false)
PrintingPolicy getPrintingPolicy() const
Retrieve a suitable printing policy for diagnostics.
ExprResult ActOnCXXThrow(Scope *S, SourceLocation OpLoc, Expr *expr)
Definition SemaExprCXX.cpp:815
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)
bool CheckConstraintSatisfaction(ConstrainedDeclOrNestedRequirement Entity, ArrayRef< AssociatedConstraint > AssociatedConstraints, const MultiLevelTemplateArgumentList &TemplateArgLists, SourceRange TemplateIDRange, ConstraintSatisfaction &Satisfaction, const ConceptReference *TopLevelConceptId=nullptr, Expr **ConvertedExpr=nullptr)
Check whether the given list of constraint expressions are satisfied (as if in a 'conjunction') given...
EnumDecl * getStdAlignValT() const
LazyDeclPtr StdBadAlloc
The C++ "std::bad_alloc" class, which is defined by the C++ standard library.
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 AddTemplateOverloadCandidate(FunctionTemplateDecl *FunctionTemplate, DeclAccessPair FoundDecl, TemplateArgumentListInfo *ExplicitTemplateArgs, ArrayRef< Expr * > Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions=false, bool PartialOverloading=false, bool AllowExplicit=true, ADLCallKind IsADLCandidate=ADLCallKind::NotADL, OverloadCandidateParamOrder PO={}, bool AggregateCandidateDeduction=false)
Add a C++ function template specialization as a candidate in the candidate set, using template argume...
bool checkLiteralOperatorId(const CXXScopeSpec &SS, const UnqualifiedId &Id, bool IsUDSuffix)
Definition SemaExprCXX.cpp:485
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)
SourceLocation getLocForEndOfToken(SourceLocation Loc, unsigned Offset=0)
Calls Lexer::getLocForEndOfToken()
@ UPPC_IfExists
Microsoft __if_exists.
@ UPPC_IfNotExists
Microsoft __if_not_exists.
const LangOptions & getLangOpts() const
StmtResult ActOnFinishFullStmt(Stmt *Stmt)
Definition SemaExprCXX.cpp:7736
CastKind PrepareScalarCast(ExprResult &src, QualType destType)
Prepares for a scalar cast, performing all the necessary stages except the final cast and returning t...
void diagnoseUnavailableAlignedAllocation(const FunctionDecl &FD, SourceLocation Loc)
Produce diagnostics if FD is an aligned allocation or deallocation function that is unavailable.
Definition SemaExprCXX.cpp:2120
bool LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS, QualType ObjectType, bool AllowBuiltinCreation=false, bool EnteringContext=false)
Performs name lookup for a name that was parsed in the source code, and may contain a C++ scope speci...
bool DiagnoseUnexpandedParameterPack(SourceLocation Loc, TypeSourceInfo *T, UnexpandedParameterPackContext UPPC)
If the given type contains an unexpanded parameter pack, diagnose the error.
bool RequireNonAbstractType(SourceLocation Loc, QualType T, TypeDiagnoser &Diagnoser)
ExprResult ActOnCXXBoolLiteral(SourceLocation OpLoc, tok::TokenKind Kind)
ActOnCXXBoolLiteral - Parse {true,false} literals.
Definition SemaExprCXX.cpp:802
ExprResult BuildCXXTypeConstructExpr(TypeSourceInfo *Type, SourceLocation LParenLoc, MultiExprArg Exprs, SourceLocation RParenLoc, bool ListInitialization)
Definition SemaExprCXX.cpp:1519
AssignConvertType CheckAssignmentConstraints(SourceLocation Loc, QualType LHSType, QualType RHSType)
CheckAssignmentConstraints - Perform type checking for assignment, argument passing,...
void AddOverloadCandidate(FunctionDecl *Function, DeclAccessPair FoundDecl, ArrayRef< Expr * > Args, OverloadCandidateSet &CandidateSet, bool SuppressUserConversions=false, bool PartialOverloading=false, bool AllowExplicit=true, bool AllowExplicitConversion=false, ADLCallKind IsADLCandidate=ADLCallKind::NotADL, ConversionSequenceList EarlyConversions={}, OverloadCandidateParamOrder PO={}, bool AggregateCandidateDeduction=false, bool StrictPackMatch=false)
AddOverloadCandidate - Adds the given function to the set of candidate functions, using the given fun...
const LangOptions & LangOpts
sema::LambdaScopeInfo * getCurLambda(bool IgnoreNonLambdaCapturingScope=false)
Retrieve the current lambda scope info, if any.
ExprResult BuildCXXMemberCallExpr(Expr *Exp, NamedDecl *FoundDecl, CXXConversionDecl *Method, bool HadMultipleCandidates)
ExprResult CheckConditionVariable(VarDecl *ConditionVar, SourceLocation StmtLoc, ConditionKind CK)
Check the use of the given variable as a C++ condition in an if, while, do-while, or switch statement...
Definition SemaExprCXX.cpp:4414
ExprResult TemporaryMaterializationConversion(Expr *E)
If E is a prvalue denoting an unmaterialized temporary, materialize it as an xvalue.
CXXRecordDecl * getStdBadAlloc() const
ExprResult ActOnCXXTypeConstructExpr(ParsedType TypeRep, SourceLocation LParenOrBraceLoc, MultiExprArg Exprs, SourceLocation RParenOrBraceLoc, bool ListInitialization)
ActOnCXXTypeConstructExpr - Parse construction of a specified type.
Definition SemaExprCXX.cpp:1497
void CheckUnusedVolatileAssignment(Expr *E)
Check whether E, which is either a discarded-value expression or an unevaluated operand,...
QualType CheckTypenameType(ElaboratedTypeKeyword Keyword, SourceLocation KeywordLoc, NestedNameSpecifierLoc QualifierLoc, const IdentifierInfo &II, SourceLocation IILoc, TypeSourceInfo **TSI, bool DeducedTSTContext)
bool CanUseDecl(NamedDecl *D, bool TreatUnavailableAsInvalid)
Determine whether the use of this declaration is valid, without emitting diagnostics.
ConditionResult ActOnConditionVariable(Decl *ConditionVar, SourceLocation StmtLoc, ConditionKind CK)
Definition SemaExprCXX.cpp:4402
void MarkAnyDeclReferenced(SourceLocation Loc, Decl *D, bool MightBeOdrUse)
Perform marking for a reference to an arbitrary declaration.
void MarkVTableUsed(SourceLocation Loc, CXXRecordDecl *Class, bool DefinitionRequired=false)
Note that the vtable for the given class was used at the given location.
bool CheckAllocatedType(QualType AllocType, SourceLocation Loc, SourceRange R)
Checks that a type is suitable as the allocated type in a new-expression.
Definition SemaExprCXX.cpp:2653
CleanupInfo Cleanup
Used to control the generation of ExprWithCleanups.
ExprResult ActOnRequiresExpr(SourceLocation RequiresKWLoc, RequiresExprBodyDecl *Body, SourceLocation LParenLoc, ArrayRef< ParmVarDecl * > LocalParameters, SourceLocation RParenLoc, ArrayRef< concepts::Requirement * > Requirements, SourceLocation ClosingBraceLoc)
Definition SemaExprCXX.cpp:8036
QualType FindCompositePointerType(SourceLocation Loc, Expr *&E1, Expr *&E2, bool ConvertArgs=true)
Find a merged pointer type and convert the two expressions to it.
Definition SemaExprCXX.cpp:6110
static CastKind ScalarTypeToBooleanCastKind(QualType ScalarTy)
ScalarTypeToBooleanCastKind - Returns the cast kind corresponding to the conversion from scalar type ...
ReferenceConversionsScope::ReferenceConversions ReferenceConversions
CXXRecordDecl * getCurrentClass(Scope *S, const CXXScopeSpec *SS)
Get the class that is directly named by the current context.
ExprResult BuildCXXUuidof(QualType TypeInfoType, SourceLocation TypeidLoc, TypeSourceInfo *Operand, SourceLocation RParenLoc)
Build a Microsoft __uuidof expression with a type operand.
Definition SemaExprCXX.cpp:735
MemberPointerConversionResult CheckMemberPointerConversion(QualType FromType, const MemberPointerType *ToPtrType, CastKind &Kind, CXXCastPath &BasePath, SourceLocation CheckLoc, SourceRange OpRange, bool IgnoreBaseAccess, MemberPointerConversionDirection Direction)
CheckMemberPointerConversion - Check the member pointer conversion from the expression From to the ty...
Expr * BuildCXXThisExpr(SourceLocation Loc, QualType Type, bool IsImplicit)
Build a CXXThisExpr and mark it referenced in the current context.
Definition SemaExprCXX.cpp:1437
QualType CheckSizelessVectorOperands(ExprResult &LHS, ExprResult &RHS, SourceLocation Loc, bool IsCompAssign, ArithConvKind OperationKind)
llvm::DenseMap< const VarDecl *, int > RefsMinusAssignments
Increment when we find a reference; decrement when we find an ignored assignment.
QualType DeduceTemplateSpecializationFromInitializer(TypeSourceInfo *TInfo, const InitializedEntity &Entity, const InitializationKind &Kind, MultiExprArg Init)
void MarkThisReferenced(CXXThisExpr *This)
Definition SemaExprCXX.cpp:1444
ExprResult DefaultLvalueConversion(Expr *E)
bool CheckDerivedToBaseConversion(QualType Derived, QualType Base, SourceLocation Loc, SourceRange Range, CXXCastPath *BasePath=nullptr, bool IgnoreAccess=false)
bool isInLifetimeExtendingContext() const
Module * getCurrentModule() const
Get the module unit whose scope we are currently within.
AssignConvertType CheckTransparentUnionArgumentConstraints(QualType ArgType, ExprResult &RHS)
static bool isCast(CheckedConversionKind CCK)
ExprResult prepareVectorSplat(QualType VectorTy, Expr *SplattedExpr)
Prepare SplattedExpr for a vector splat operation, adding implicit casts if necessary.
DeclContext * CurContext
CurContext - This is the current declaration context of parsing.
bool FindAllocationFunctions(SourceLocation StartLoc, SourceRange Range, AllocationFunctionScope NewScope, AllocationFunctionScope DeleteScope, QualType AllocType, bool IsArray, ImplicitAllocationParameters &IAP, MultiExprArg PlaceArgs, FunctionDecl *&OperatorNew, FunctionDecl *&OperatorDelete, bool Diagnose=true)
Finds the overloads of operator new and delete that are appropriate for the allocation.
Definition SemaExprCXX.cpp:2927
DeclarationNameInfo GetNameFromUnqualifiedId(const UnqualifiedId &Name)
Retrieves the declaration name from a parsed unqualified-id.
ExprResult PerformContextuallyConvertToBool(Expr *From)
PerformContextuallyConvertToBool - Perform a contextual conversion of the expression From to bool (C+...
AccessResult CheckConstructorAccess(SourceLocation Loc, CXXConstructorDecl *D, DeclAccessPair FoundDecl, const InitializedEntity &Entity, bool IsCopyBindingRefToTemp=false)
Checks access to a constructor.
bool DiagnoseConditionalForNull(const Expr *LHSExpr, const Expr *RHSExpr, SourceLocation QuestionLoc)
Emit a specialized diagnostic when one expression is a null pointer constant and the other is not a p...
ParsedType getDestructorTypeForDecltype(const DeclSpec &DS, ParsedType ObjectType)
Definition SemaExprCXX.cpp:458
bool IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived, CXXRecordDecl *Base, CXXBasePaths &Paths)
Determine whether the type Derived is a C++ class that is derived from the type Base.
bool isUnevaluatedContext() const
Determines whether we are currently in a context that is not evaluated as per C++ [expr] p5.
DeclContext * getFunctionLevelDeclContext(bool AllowLambda=false) const
If AllowLambda is true, treat lambda as function.
Stmt * MaybeCreateStmtWithCleanups(Stmt *SubStmt)
Definition SemaExprCXX.cpp:6689
ExprResult ActOnCXXNew(SourceLocation StartLoc, bool UseGlobal, SourceLocation PlacementLParen, MultiExprArg PlacementArgs, SourceLocation PlacementRParen, SourceRange TypeIdParens, Declarator &D, Expr *Initializer)
Parsed a C++ 'new' expression (C++ 5.3.4).
Definition SemaExprCXX.cpp:2015
ExprResult BuildCXXNoexceptExpr(SourceLocation KeyLoc, Expr *Operand, SourceLocation RParen)
Definition SemaExprCXX.cpp:7353
bool GlobalNewDeleteDeclared
A flag to remember whether the implicit forms of operator new and delete have been declared.
ExprResult ActOnParenExpr(SourceLocation L, SourceLocation R, Expr *E)
ExprResult CheckPlaceholderExpr(Expr *E)
Check for operands with placeholder types and complain if found.
ExprResult TransformToPotentiallyEvaluated(Expr *E)
ExprResult BuildCXXConstructExpr(SourceLocation ConstructLoc, QualType DeclInitType, NamedDecl *FoundDecl, CXXConstructorDecl *Constructor, MultiExprArg Exprs, bool HadMultipleCandidates, bool IsListInitialization, bool IsStdInitListInitialization, bool RequiresZeroInit, CXXConstructionKind ConstructKind, SourceRange ParenRange)
BuildCXXConstructExpr - Creates a complete call to a constructor, including handling of its default a...
bool inTemplateInstantiation() const
Determine whether we are currently performing template instantiation.
SourceManager & getSourceManager() const
QualType CXXThisTypeOverride
When non-NULL, the C++ 'this' expression is allowed despite the current context not being a non-stati...
ExprResult FixOverloadedFunctionReference(Expr *E, DeclAccessPair FoundDecl, FunctionDecl *Fn)
FixOverloadedFunctionReference - E is an expression that refers to a C++ overloaded function (possibl...
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.
ExprResult CheckCXXBooleanCondition(Expr *CondExpr, bool IsConstexpr=false)
CheckCXXBooleanCondition - Returns true if conversion to bool is invalid.
Definition SemaExprCXX.cpp:4451
CanThrowResult canThrow(const Stmt *E)
bool isThisOutsideMemberFunctionBody(QualType BaseType)
Determine whether the given type is the type of *this that is used outside of the body of a member fu...
Definition SemaExprCXX.cpp:1484
DeclContext * computeDeclContext(QualType T)
Compute the DeclContext that is associated with the given type.
QualType CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS, ExprValueKind &VK, SourceLocation OpLoc, bool isIndirect)
Definition SemaExprCXX.cpp:5353
concepts::ExprRequirement * BuildExprRequirement(Expr *E, bool IsSatisfied, SourceLocation NoexceptLoc, concepts::ExprRequirement::ReturnTypeRequirement ReturnTypeRequirement)
Definition SemaExprCXX.cpp:7875
QualType CXXCheckConditionalOperands(ExprResult &cond, ExprResult &lhs, ExprResult &rhs, ExprValueKind &VK, ExprObjectKind &OK, SourceLocation questionLoc)
Check the operands of ?
Definition SemaExprCXX.cpp:5817
ExprResult PerformImplicitConversion(Expr *From, QualType ToType, const ImplicitConversionSequence &ICS, AssignmentAction Action, CheckedConversionKind CCK=CheckedConversionKind::Implicit)
PerformImplicitConversion - Perform an implicit conversion of the expression From to the type ToType ...
Definition SemaExprCXX.cpp:4587
bool isSFINAEContext() const
bool DiagnoseUseOfDecl(NamedDecl *D, ArrayRef< SourceLocation > Locs, const ObjCInterfaceDecl *UnknownObjCClass=nullptr, bool ObjCPropertyAccess=false, bool AvoidPartialAvailabilityChecks=false, ObjCInterfaceDecl *ClassReciever=nullptr, bool SkipTrailingRequiresClause=false)
Determine whether the use of this declaration is valid, and emit any corresponding diagnostics.
concepts::Requirement * ActOnTypeRequirement(SourceLocation TypenameKWLoc, CXXScopeSpec &SS, SourceLocation NameLoc, const IdentifierInfo *TypeName, TemplateIdAnnotation *TemplateId)
Definition SemaExprCXX.cpp:7798
void CheckShadow(NamedDecl *D, NamedDecl *ShadowedDecl, const LookupResult &R)
Diagnose variable or built-in function shadowing.
ParsedType getInheritingConstructorName(CXXScopeSpec &SS, SourceLocation NameLoc, const IdentifierInfo &Name)
Handle the result of the special case name lookup for inheriting constructor declarations.
Definition SemaExprCXX.cpp:57
TypeResult ActOnTypenameType(Scope *S, SourceLocation TypenameLoc, const CXXScopeSpec &SS, const IdentifierInfo &II, SourceLocation IdLoc, ImplicitTypenameContext IsImplicitTypename=ImplicitTypenameContext::No)
Called when the parser has parsed a C++ typename specifier, e.g., "typename T::type".
bool isCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind=CompleteTypeKind::Default)
ExprResult BuildPseudoDestructorExpr(Expr *Base, SourceLocation OpLoc, tok::TokenKind OpKind, const CXXScopeSpec &SS, TypeSourceInfo *ScopeType, SourceLocation CCLoc, SourceLocation TildeLoc, PseudoDestructorTypeStorage DestroyedType)
Definition SemaExprCXX.cpp:7050
RecordDecl * CXXTypeInfoDecl
The C++ "type_info" declaration, which is defined in .
CXXConstructorDecl * LookupCopyingConstructor(CXXRecordDecl *Class, unsigned Quals)
Look up the copying constructor for the given class.
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 ...
ParsedType getTypeName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec *SS=nullptr, bool isClassName=false, bool HasTrailingDot=false, ParsedType ObjectType=nullptr, bool IsCtorOrDtorName=false, bool WantNontrivialTypeSourceInfo=false, bool IsClassTemplateDeductionContext=true, ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No, IdentifierInfo **CorrectedII=nullptr)
If the identifier refers to a type name within this scope, return the declaration of that type.
RequiresExprBodyDecl * ActOnStartRequiresExpr(SourceLocation RequiresKWLoc, ArrayRef< ParmVarDecl * > LocalParameters, Scope *BodyScope)
Definition SemaExprCXX.cpp:7976
bool CheckPointerConversion(Expr *From, QualType ToType, CastKind &Kind, CXXCastPath &BasePath, bool IgnoreBaseAccess, bool Diagnose=true)
CheckPointerConversion - Check the pointer conversion from the expression From to the type ToType.
SmallVector< ExprWithCleanups::CleanupObject, 8 > ExprCleanupObjects
ExprCleanupObjects - This is the stack of objects requiring cleanup that are created by the current f...
void NoteDeletedFunction(FunctionDecl *FD)
Emit a note explaining that this function is deleted.
void AddKnownFunctionAttributesForReplaceableGlobalAllocationFunction(FunctionDecl *FD)
If this function is a C++ replaceable global allocation function (C++2a [basic.stc....
QualType BuildDecltypeType(Expr *E, bool AsUnevaluated=true)
If AsUnevaluated is false, E is treated as though it were an evaluated context, such as when building...
TypeSourceInfo * GetTypeForDeclarator(Declarator &D)
GetTypeForDeclarator - Convert the type for the specified declarator to Type instances.
bool CheckCallReturnType(QualType ReturnType, SourceLocation Loc, CallExpr *CE, FunctionDecl *FD)
CheckCallReturnType - Checks that a call expression's return type is complete.
bool RequireCompleteType(SourceLocation Loc, QualType T, CompleteTypeKind Kind, TypeDiagnoser &Diagnoser)
Ensure that the type T is a complete type.
ReferenceCompareResult CompareReferenceRelationship(SourceLocation Loc, QualType T1, QualType T2, ReferenceConversions *Conv=nullptr)
CompareReferenceRelationship - Compare the two types T1 and T2 to determine whether they are referenc...
ExprResult forceUnknownAnyToType(Expr *E, QualType ToType)
Force an expression with unknown-type to an expression of the given type.
bool LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx, bool InUnqualifiedLookup=false)
Perform qualified name lookup into a given context.
llvm::MapVector< FieldDecl *, DeleteLocs > DeleteExprs
Delete-expressions to be analyzed at the end of translation unit.
Expr * MaybeCreateExprWithCleanups(Expr *SubExpr)
MaybeCreateExprWithCleanups - If the current full-expression requires any cleanups,...
Definition SemaExprCXX.cpp:6667
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.
bool isDependentScopeSpecifier(const CXXScopeSpec &SS)
bool isUnavailableAlignedAllocationFunction(const FunctionDecl &FD) const
Determine whether FD is an aligned allocation or deallocation function that is unavailable.
Definition SemaExprCXX.cpp:2106
DiagnosticsEngine & Diags
TypeAwareAllocationMode ShouldUseTypeAwareOperatorNewOrDelete() const
NamespaceDecl * getStdNamespace() const
ExprResult BuildCXXThrow(SourceLocation OpLoc, Expr *Ex, bool IsThrownVarInScope)
Definition SemaExprCXX.cpp:851
ExprResult DefaultFunctionArrayConversion(Expr *E, bool Diagnose=true)
DefaultFunctionArrayConversion (C99 6.3.2.1p3, C99 6.3.2.1p4).
ExprResult PerformCopyInitialization(const InitializedEntity &Entity, SourceLocation EqualLoc, ExprResult Init, bool TopLevelOfInitList=false, bool AllowExplicit=false)
bool CheckQualifiedFunctionForTypeId(QualType T, SourceLocation Loc)
friend class InitializationSequence
concepts::NestedRequirement * BuildNestedRequirement(Expr *E)
Definition SemaExprCXX.cpp:7956
TemplateDeductionResult DeduceTemplateArguments(ClassTemplatePartialSpecializationDecl *Partial, ArrayRef< TemplateArgument > TemplateArgs, sema::TemplateDeductionInfo &Info)
QualType ActOnPackIndexingType(QualType Pattern, Expr *IndexExpr, SourceLocation Loc, SourceLocation EllipsisLoc)
bool isUsualDeallocationFunction(const CXXMethodDecl *FD)
Definition SemaExprCXX.cpp:1686
TypeResult ActOnTemplateIdType(Scope *S, ElaboratedTypeKeyword ElaboratedKeyword, SourceLocation ElaboratedKeywordLoc, CXXScopeSpec &SS, SourceLocation TemplateKWLoc, TemplateTy Template, const IdentifierInfo *TemplateII, SourceLocation TemplateIILoc, SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc, bool IsCtorOrDtorName=false, bool IsClassName=false, ImplicitTypenameContext AllowImplicitTypename=ImplicitTypenameContext::No)
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...
void MarkFunctionReferenced(SourceLocation Loc, FunctionDecl *Func, bool MightBeOdrUse=true)
Mark a function referenced, and check whether it is odr-used (C++ [basic.def.odr]p2,...
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.
ParsedType getConstructorName(const IdentifierInfo &II, SourceLocation NameLoc, Scope *S, CXXScopeSpec &SS, bool EnteringContext)
Definition SemaExprCXX.cpp:71
LazyDeclPtr StdAlignValT
The C++ "std::align_val_t" enum class, which is defined by the C++ standard library.
@ Diagnose
Diagnose issues that are non-constant or that are extensions.
bool CheckCXXThrowOperand(SourceLocation ThrowLoc, QualType ThrowTy, Expr *E)
CheckCXXThrowOperand - Validate the operand of a throw.
Definition SemaExprCXX.cpp:965
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)
bool LookupName(LookupResult &R, Scope *S, bool AllowBuiltinCreation=false, bool ForceNoCPlusPlus=false)
Perform unqualified name lookup starting from a given scope.
static QualType GetTypeFromParser(ParsedType Ty, TypeSourceInfo **TInfo=nullptr)
concepts::Requirement * ActOnNestedRequirement(Expr *Constraint)
Definition SemaExprCXX.cpp:7951
QualType adjustCCAndNoReturn(QualType ArgFunctionType, QualType FunctionType, bool AdjustExceptionSpec=false)
Adjust the type ArgFunctionType to match the calling convention, noreturn, and optionally the excepti...
bool IsStringLiteralToNonConstPointerConversion(Expr *From, QualType ToType)
Helper function to determine whether this is the (deprecated) C++ conversion from a string literal to...
Definition SemaExprCXX.cpp:4485
bool CheckExceptionSpecCompatibility(Expr *From, QualType ToType)
static ConditionResult ConditionError()
IdentifierResolver IdResolver
FunctionTemplateDecl * getMoreSpecializedTemplate(FunctionTemplateDecl *FT1, FunctionTemplateDecl *FT2, SourceLocation Loc, TemplatePartialOrderingContext TPOC, unsigned NumCallArguments1, QualType RawObj1Ty={}, QualType RawObj2Ty={}, bool Reversed=false, bool PartialOverloading=false)
Returns the more specialized function template according to the rules of function template partial or...
ExprResult ActOnCXXThis(SourceLocation Loc)
Definition SemaExprCXX.cpp:1398
ExprResult ActOnDecltypeExpression(Expr *E)
Process the expression contained within a decltype.
Definition SemaExprCXX.cpp:6710
bool CheckCXXDefaultArgExpr(SourceLocation CallLoc, FunctionDecl *FD, ParmVarDecl *Param, Expr *Init=nullptr, bool SkipImmediateInvocations=true)
Instantiate or parse a C++ default argument expression as necessary.
void CheckVirtualDtorCall(CXXDestructorDecl *dtor, SourceLocation Loc, bool IsDelete, bool CallCanBeVirtual, bool WarnOnNonAbstractTypes, SourceLocation DtorLoc)
Definition SemaExprCXX.cpp:4357
ExprResult ActOnFinishFullExpr(Expr *Expr, bool DiscardedValue)
void checkCall(NamedDecl *FDecl, const FunctionProtoType *Proto, const Expr *ThisArg, ArrayRef< const Expr * > Args, bool IsMemberFunction, SourceLocation Loc, SourceRange Range, VariadicCallType CallType)
Handles the checks for format strings, non-POD arguments to vararg functions, NULL arguments passed t...
Encodes a location in the source.
bool isValid() const
Return true if this is a valid SourceLocation object.
A trivial tuple used to represent a source range.
SourceLocation getEnd() const
SourceLocation getBegin() const
StandardConversionSequence - represents a standard conversion sequence (C++ 13.3.3....
DeclAccessPair FoundCopyConstructor
ImplicitConversionKind Second
Second - The second conversion can be an integral promotion, floating point promotion,...
ImplicitConversionKind First
First – The first conversion can be an lvalue-to-rvalue conversion, array-to-pointer conversion,...
unsigned DeprecatedStringLiteralToCharPtr
Whether this is the deprecated conversion of a string literal to a pointer to non-const character dat...
CXXConstructorDecl * CopyConstructor
CopyConstructor - The copy constructor that is used to perform this conversion, when the conversion i...
unsigned IncompatibleObjC
IncompatibleObjC - Whether this is an Objective-C conversion that we should warn about (if we actuall...
ImplicitConversionKind Third
Third - The third conversion can be a qualification conversion or a function conversion.
ImplicitConversionKind Dimension
Dimension - Between the second and third conversion a vector or matrix dimension conversion may occur...
StmtExpr - This is the GNU Statement Expression extension: ({int X=4; X;}).
Stmt - This represents one statement.
SourceLocation getEndLoc() const LLVM_READONLY
SourceRange getSourceRange() const LLVM_READONLY
SourceLocation tokens are not useful in isolation - they are low level value objects created/interpre...
SourceLocation getBeginLoc() const LLVM_READONLY
StringLiteral - This represents a string literal expression, e.g.
StringRef getString() const
unsigned getNewAlign() const
Return the largest alignment for which a suitably-sized allocation with 'operator new(size_t)' is gua...
const llvm::Triple & getTriple() const
Returns the target triple of the primary target.
A template argument list.
ArrayRef< TemplateArgument > asArray() const
Produce this as an array ref.
Represents a template argument.
@ Declaration
The template argument is a declaration that was provided for a pointer, reference,...
@ Type
The template argument is a type.
Stores a list of template parameters for a TemplateDecl and its derived classes.
NamedDecl * getParam(unsigned Idx)
unsigned getDepth() const
Get the depth of this template parameter list in the set of template parameter lists.
static TemplateParameterList * Create(const ASTContext &C, SourceLocation TemplateLoc, SourceLocation LAngleLoc, ArrayRef< NamedDecl * > Params, SourceLocation RAngleLoc, Expr *RequiresClause)
static TemplateTypeParmDecl * Create(const ASTContext &C, DeclContext *DC, SourceLocation KeyLoc, SourceLocation NameLoc, unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack, bool HasTypeConstraint=false, UnsignedOrNone NumExpanded=std::nullopt)
Models the abbreviated syntax to constrain a template type parameter: template <convertible_to<string...
Expr * getImmediatelyDeclaredConstraint() const
Get the immediately-declared constraint expression introduced by this type-constraint,...
Represents a declaration of a type.
TyLocType push(QualType T)
Pushes space for a new TypeLoc of the given type.
TypeSourceInfo * getTypeSourceInfo(ASTContext &Context, QualType T)
Creates a TypeSourceInfo for the given type.
void pushTrivial(ASTContext &Context, QualType T, SourceLocation Loc)
Pushes 'T' with all locations pointing to 'Loc'.
SourceRange getSourceRange() const LLVM_READONLY
Get the full source range.
SourceLocation getBeginLoc() const
Get the begin source location.
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 isSizelessType() const
As an extension, we classify types as one of "sized" or "sizeless"; every type is one or the other.
bool isBlockPointerType() const
bool isBooleanType() const
bool isPlaceholderType() const
Test for a type which does not represent an actual type-system type but is instead used as a placehol...
CXXRecordDecl * getAsCXXRecordDecl() const
Retrieves the CXXRecordDecl that this type refers to, either because the type is a RecordType or beca...
bool isVoidPointerType() const
CXXRecordDecl * castAsCXXRecordDecl() const
bool isArithmeticType() const
bool isConstantMatrixType() const
bool isPointerType() const
bool isArrayParameterType() const
bool isIntegerType() const
isIntegerType() does not include complex integers (a GCC extension).
const T * castAs() const
Member-template castAs.
bool isReferenceType() const
bool isEnumeralType() const
bool isScalarType() const
bool isSveVLSBuiltinType() const
Determines if this is a sizeless type supported by the 'arm_sve_vector_bits' type attribute,...
bool isIntegralType(const ASTContext &Ctx) const
Determine whether this type is an integral type.
QualType getPointeeType() const
If this is a pointer, ObjC object pointer, or block pointer, this returns the respective pointee.
bool isExtVectorType() const
TagDecl * getAsTagDecl() const
Retrieves the TagDecl that this type refers to, either because the type is a TagType or because it is...
bool isBuiltinType() const
Helper methods to distinguish type categories.
bool isDependentType() const
Whether this type is a dependent type, meaning that its definition somehow depends on a template para...
bool isFixedPointType() const
Return true if this is a fixed point type according to ISO/IEC JTC1 SC22 WG14 N1169.
DeducedType * getContainedDeducedType() const
Get the DeducedType whose type will be deduced for a variable with an initializer of this type.
bool isWebAssemblyTableType() const
Returns true if this is a WebAssembly table type: either an array of reference types,...
const Type * getBaseElementTypeUnsafe() const
Get the base element type of this type, potentially discarding type qualifiers.
bool isMemberPointerType() const
bool isMatrixType() const
EnumDecl * castAsEnumDecl() const
bool isVariablyModifiedType() const
Whether this type is a variably-modified type (C99 6.7.5).
bool isObjCLifetimeType() const
Returns true if objects of this type have lifetime semantics under ARC.
bool isObjectType() const
Determine whether this type is an object type.
EnumDecl * getAsEnumDecl() const
Retrieves the EnumDecl this type refers to.
bool isPointerOrReferenceType() const
Qualifiers::ObjCLifetime getObjCARCImplicitLifetime() const
Return the implicit lifetime for this type, which must not be dependent.
bool isFunctionType() const
bool isObjCObjectPointerType() const
bool isVectorType() const
bool isRealFloatingType() const
Floating point categories.
const T * getAsCanonical() const
If this type is canonically the specified type, return its canonical type cast to that specified type...
bool isFloatingType() const
bool isAnyPointerType() const
const T * getAs() const
Member-template getAs'.
bool isObjCARCImplicitlyUnretainedType() const
Determines if this type, which must satisfy isObjCLifetimeType(), is implicitly __unsafe_unretained r...
bool isNullPtrType() const
bool isRecordType() const
bool isObjCRetainableType() const
bool isSizelessVectorType() const
Returns true for all scalable vector types.
UnaryOperator - This represents the unary-expression's (except sizeof and alignof),...
Represents a C++ unqualified-id that has been parsed.
SourceLocation getBeginLoc() const LLVM_READONLY
SourceRange getSourceRange() const LLVM_READONLY
Return the source range that covers this unqualified-id.
SourceLocation getEndLoc() const LLVM_READONLY
SourceLocation StartLocation
The location of the first token that describes this unqualified-id, which will be the location of the...
const IdentifierInfo * Identifier
When Kind == IK_Identifier, the parsed identifier, or when Kind == IK_UserLiteralId,...
UnqualifiedIdKind getKind() const
Determine what kind of name we have.
TemplateIdAnnotation * TemplateId
When Kind == IK_TemplateId or IK_ConstructorTemplateId, the template-id annotation that contains the ...
Represent the declaration of a variable (in which case it is an lvalue) a function (in which case it ...
bool isWeak() const
Determine whether this symbol is weakly-imported, or declared with the weak or weak-ref attr.
VarDecl * getPotentiallyDecomposedVarDecl()
Represents a variable declaration or definition.
SourceRange getSourceRange() const override LLVM_READONLY
Source range that this declaration covers.
bool isUsableInConstantExpressions(const ASTContext &C) const
Determine whether this variable's value can be used in a constant expression, according to the releva...
const Expr * getAnyInitializer() const
Get the initializer for this variable, no matter which declaration it is attached to.
Represents a GCC generic vector type.
bool isTypeConstraint() const
TemplateParameterList * getTypeConstraintTemplateParameterList() const
bool isSubstitutionFailure() const
A requires-expression requirement which queries the validity and properties of an expression ('simple...
@ SS_ConstraintsNotSatisfied
@ SS_TypeRequirementSubstitutionFailure
A requires-expression requirement which is satisfied when a general constraint expression is satisfie...
A static requirement that can be used in a requires-expression to check properties of types and expre...
A requires-expression requirement which queries the existence of a type name or type template special...
ImplicitCaptureStyle ImpCaptureStyle
Capture & getCXXThisCapture()
Retrieve the capture of C++ 'this', if it has been captured.
bool isCXXThisCaptured() const
Determine whether the C++ 'this' is captured.
void addThisCapture(bool isNested, SourceLocation Loc, QualType CaptureType, bool ByCopy)
SourceLocation PotentialThisCaptureLocation
bool hasPotentialThisCapture() const
SourceRange IntroducerRange
Source range covering the lambda introducer [...].
bool lambdaCaptureShouldBeConst() const
void clearPotentialCaptures()
bool hasPotentialCaptures() const
bool isVariableExprMarkedAsNonODRUsed(Expr *CapturingVarExpr) const
CXXRecordDecl * Lambda
The class that describes the lambda.
void visitPotentialCaptures(llvm::function_ref< void(ValueDecl *, Expr *)> Callback) const
unsigned NumExplicitCaptures
The number of captures in the Captures list that are explicit captures.
bool AfterParameterList
Indicate that we parsed the parameter list at which point the mutability of the lambda is known.
CXXMethodDecl * CallOperator
The lambda's compiler-generated operator().
Provides information about an attempted template argument deduction, whose success or failure was des...
Defines the clang::TargetInfo interface.
SmallVector< BoundNodes, 1 > match(MatcherT Matcher, const NodeT &Node, ASTContext &Context)
Returns the results of matching Matcher on Node.
bool NE(InterpState &S, CodePtr OpPC)
ComparisonCategoryResult Compare(const T &X, const T &Y)
Helper to compare two comparable types.
TokenKind
Provides a simple uniform namespace for tokens from all C languages.
The JSON file list parser is used to communicate input to InstallAPI.
CanQual< Type > CanQualType
Represents a canonical, potentially-qualified type.
bool isLambdaCallWithImplicitObjectParameter(const DeclContext *DC)
OverloadedOperatorKind
Enumeration specifying the different kinds of C++ overloaded operators.
@ Match
This is not an overload because the signature exactly matches an existing declaration.
bool isa(CodeGen::Address addr)
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.
@ OR_Ambiguous
Ambiguous candidates found.
@ OR_No_Viable_Function
No viable function found.
CanThrowResult
Possible results from evaluation of a noexcept expression.
AllocationFunctionScope
The scope in which to find allocation functions.
@ Both
Look for allocation functions in both the global scope and in the scope of the allocated class.
@ Global
Only look for allocation functions in the global scope.
@ Class
Only look for allocation functions in the scope of the allocated class.
DeclContext * getLambdaAwareParentOfDeclContext(DeclContext *DC)
bool isReservedInAllContexts(ReservedIdentifierStatus Status)
Determine whether an identifier is reserved in all contexts.
bool isUnresolvedExceptionSpec(ExceptionSpecificationType ESpecType)
@ Ambiguous
Name lookup results in an ambiguity; use getAmbiguityKind to figure out what kind of ambiguity we hav...
@ NotFound
No entity found met the criteria.
@ FoundOverloaded
Name lookup found a set of overloaded functions that met the criteria.
@ Found
Name lookup found a single declaration that met the criteria.
@ FoundUnresolvedValue
Name lookup found an unresolvable value declaration and cannot yet complete.
@ NotFoundInCurrentInstantiation
No entity found met the criteria within the current instantiation,, but there were dependent base cla...
AlignedAllocationMode alignedAllocationModeFromBool(bool IsAligned)
@ Conditional
A conditional (?:) operator.
@ RQ_None
No ref-qualifier was provided.
@ RQ_LValue
An lvalue ref-qualifier was provided (&).
@ RQ_RValue
An rvalue ref-qualifier was provided (&&).
@ OCD_AmbiguousCandidates
Requests that only tied-for-best candidates be shown.
@ OCD_AllCandidates
Requests that all candidates be shown.
ExprObjectKind
A further classification of the kind of object referenced by an l-value or x-value.
@ OK_ObjCProperty
An Objective-C property is a logical field of an Objective-C object which is read and written via Obj...
@ OK_Ordinary
An ordinary object is located at an address in memory.
@ OK_BitField
A bitfield object is a bitfield on a C or C++ record.
UnsignedOrNone getStackIndexOfNearestEnclosingCaptureCapableLambda(ArrayRef< const sema::FunctionScopeInfo * > FunctionScopes, ValueDecl *VarToCapture, Sema &S)
Examines the FunctionScopeInfo stack to determine the nearest enclosing lambda (to the current lambda...
@ LCK_StarThis
Capturing the *this object by copy.
@ Bind
'bind' clause, allowed on routine constructs.
@ Self
'self' clause, allowed on Compute and Combined Constructs, plus 'update'.
@ IK_TemplateId
A template-id, e.g., f.
@ IK_LiteralOperatorId
A user-defined literal name, e.g., operator "" _i.
@ IK_Identifier
An identifier.
nullptr
This class represents a compute construct, representing a 'Kind' of ‘parallel’, 'serial',...
bool isLambdaCallWithExplicitObjectParameter(const DeclContext *DC)
bool isAlignedAllocation(AlignedAllocationMode Mode)
MutableArrayRef< Expr * > MultiExprArg
bool isLambdaCallOperator(const CXXMethodDecl *MD)
@ Result
The result type of a method or function.
ActionResult< ParsedType > TypeResult
const FunctionProtoType * T
@ ICK_Complex_Conversion
Complex conversions (C99 6.3.1.6)
@ ICK_Floating_Promotion
Floating point promotions (C++ [conv.fpprom])
@ ICK_Boolean_Conversion
Boolean conversions (C++ [conv.bool])
@ ICK_Integral_Conversion
Integral conversions (C++ [conv.integral])
@ ICK_Fixed_Point_Conversion
Fixed point type conversions according to N1169.
@ ICK_Vector_Conversion
Vector conversions.
@ ICK_Block_Pointer_Conversion
Block Pointer conversions.
@ ICK_Pointer_Member
Pointer-to-member conversions (C++ [conv.mem])
@ ICK_Floating_Integral
Floating-integral conversions (C++ [conv.fpint])
@ ICK_HLSL_Array_RValue
HLSL non-decaying array rvalue cast.
@ ICK_SVE_Vector_Conversion
Arm SVE Vector conversions.
@ ICK_HLSL_Vector_Truncation
HLSL vector truncation.
@ ICK_Incompatible_Pointer_Conversion
C-only conversion between pointers with incompatible types.
@ ICK_Array_To_Pointer
Array-to-pointer conversion (C++ [conv.array])
@ ICK_RVV_Vector_Conversion
RISC-V RVV Vector conversions.
@ ICK_Complex_Promotion
Complex promotions (Clang extension)
@ ICK_Num_Conversion_Kinds
The number of conversion kinds.
@ ICK_Function_Conversion
Function pointer conversion (C++17 [conv.fctptr])
@ ICK_Vector_Splat
A vector splat from an arithmetic type.
@ ICK_Zero_Queue_Conversion
Zero constant to queue.
@ ICK_Identity
Identity conversion (no conversion)
@ ICK_Derived_To_Base
Derived-to-base (C++ [over.best.ics])
@ ICK_Lvalue_To_Rvalue
Lvalue-to-rvalue conversion (C++ [conv.lval])
@ ICK_Qualification
Qualification conversions (C++ [conv.qual])
@ ICK_Pointer_Conversion
Pointer conversions (C++ [conv.ptr])
@ ICK_TransparentUnionConversion
Transparent Union Conversions.
@ ICK_Integral_Promotion
Integral promotions (C++ [conv.prom])
@ ICK_HLSL_Matrix_Truncation
HLSL Matrix truncation.
@ ICK_Floating_Conversion
Floating point conversions (C++ [conv.double].
@ ICK_Compatible_Conversion
Conversions between compatible types in C99.
@ ICK_C_Only_Conversion
Conversions allowed in C, but not C++.
@ ICK_Writeback_Conversion
Objective-C ARC writeback conversion.
@ ICK_Zero_Event_Conversion
Zero constant to event (OpenCL1.2 6.12.10)
@ ICK_Complex_Real
Complex-real conversions (C99 6.3.1.7)
@ ICK_Function_To_Pointer
Function-to-pointer (C++ [conv.array])
@ Template
We are parsing a template declaration.
ActionResult< CXXBaseSpecifier * > BaseResult
llvm::VersionTuple alignedAllocMinVersion(llvm::Triple::OSType OS)
AssignConvertType
AssignConvertType - All of the 'assignment' semantic checks return this enum to indicate whether the ...
@ Incompatible
Incompatible - We reject this conversion outright, it is invalid to represent it in the AST.
@ Compatible
Compatible - the types are compatible according to the standard.
@ NotStartsWithUnderscore
@ Class
The "class" keyword.
@ Type
The name was classified as a type.
bool isTypeAwareAllocation(TypeAwareAllocationMode Mode)
LangAS
Defines the address space values used by the address space qualifier of QualType.
CastKind
CastKind - The kind of operation required for a conversion.
MutableArrayRef< ParsedTemplateArgument > ASTTemplateArgsPtr
SizedDeallocationMode sizedDeallocationModeFromBool(bool IsSized)
std::pair< SourceLocation, PartialDiagnostic > PartialDiagnosticAt
A partial diagnostic along with the source location where this diagnostic occurs.
bool isPtrSizeAddressSpace(LangAS AS)
ExprValueKind
The categorization of expression values, currently following the C++11 scheme.
@ VK_PRValue
A pr-value expression (in the C++11 taxonomy) produces a temporary value.
@ VK_LValue
An l-value expression is a reference to an object with independent storage.
SmallVector< CXXBaseSpecifier *, 4 > CXXCastPath
A simple array of base specifiers.
bool isSizedDeallocation(SizedDeallocationMode Mode)
IfExistsResult
Describes the result of an "if-exists" condition check.
@ Dependent
The name is a dependent name, so the results will differ from one instantiation to the next.
@ Exists
The symbol exists.
@ Error
An error occurred.
@ DoesNotExist
The symbol does not exist.
@ TPOC_Call
Partial ordering of function templates for a function call.
bool declaresSameEntity(const Decl *D1, const Decl *D2)
Determine whether two declarations declare the same entity.
TemplateDeductionResult
Describes the result of template argument deduction.
@ Success
Template argument deduction was successful.
@ AlreadyDiagnosed
Some error which was already diagnosed.
@ Generic
not a target-specific vector type
U cast(CodeGen::Address addr)
@ ArrayBound
Array bound in array declarator or new-expression.
OpaquePtr< QualType > ParsedType
An opaque type for threading parsed type information through the parser.
@ None
No keyword precedes the qualified type name.
@ Class
The "class" keyword introduces the elaborated-type-specifier.
@ Typename
The "typename" keyword precedes the qualified type name, e.g., typename T::type.
ActionResult< Expr * > ExprResult
@ Other
Other implicit parameter.
CXXNewInitializationStyle
@ Parens
New-expression has a C++98 paren-delimited initializer.
@ None
New-expression has no initializer as written.
@ Braces
New-expression has a C++11 list-initializer.
@ EST_BasicNoexcept
noexcept
@ EST_Dynamic
throw(T1, T2)
CheckedConversionKind
The kind of conversion being performed.
@ CStyleCast
A C-style cast.
@ ForBuiltinOverloadedOp
A conversion for an operand of a builtin overloaded operator.
@ FunctionalCast
A functional-style cast.
ActionResult< Stmt * > StmtResult
bool isGenericLambdaCallOperatorSpecialization(const CXXMethodDecl *MD)
The result of a constraint satisfaction check, containing the necessary information to diagnose an un...
static ASTConstraintSatisfaction * Rebuild(const ASTContext &C, const ASTConstraintSatisfaction &Satisfaction)
DeclarationNameInfo - A collector data type for bundling together a DeclarationName and the correspon...
DeclarationName getName() const
getName - Returns the embedded declaration name.
unsigned hasStatic
True if this dimension included the 'static' keyword.
Expr * NumElts
This is the size of the array, or null if [] or [*] was specified.
One instance of this struct is used for each type in a declarator that is parsed.
SourceLocation Loc
Loc - The place where this type was defined.
enum clang::DeclaratorChunk::@340323374315200305336204205154073066142310370142 Kind
ExceptionSpecificationType Type
The kind of exception specification this is.
ArrayRef< QualType > Exceptions
Explicitly-specified list of exception types.
Extra information about a function prototype.
ExceptionSpecInfo ExceptionSpec
unsigned CFIUncheckedCallee
FunctionType::ExtInfo ExtInfo
AlignedAllocationMode PassAlignment
TypeAwareAllocationMode PassTypeIdentity
unsigned getNumImplicitArgs() const
TypeAwareAllocationMode PassTypeIdentity
SizedDeallocationMode PassSize
AlignedAllocationMode PassAlignment
NestedNameSpecifierLoc Prefix
OverloadCandidate - A single candidate in an overload set (C++ 13.3).
Information about a template-id annotation token.
const IdentifierInfo * Name
FIXME: Temporarily stores the name of a specialization.
unsigned NumArgs
NumArgs - The number of template arguments.
SourceLocation TemplateNameLoc
TemplateNameLoc - The location of the template name within the source.
ParsedTemplateArgument * getTemplateArgs()
Retrieves a pointer to the template arguments.
SourceLocation RAngleLoc
The location of the '>' after the template argument list.
SourceLocation LAngleLoc
The location of the '<' before the template argument list.
SourceLocation TemplateKWLoc
TemplateKWLoc - The location of the template keyword.
ParsedTemplateTy Template
The declaration of the template corresponding to the template-name.
StandardConversionSequence Before
Represents the standard conversion that occurs before the actual user-defined conversion.
FunctionDecl * ConversionFunction
ConversionFunction - The function that will perform the user-defined conversion.
bool HadMultipleCandidates
HadMultipleCandidates - When this is true, it means that the conversion function was resolved from an...
StandardConversionSequence After
After - Represents the standard conversion that occurs after the actual user-defined conversion.
bool EllipsisConversion
EllipsisConversion - When this is true, it means user-defined conversion sequence starts with a ....
DeclAccessPair FoundConversionFunction
The declaration that we found via name lookup, which might be the same as ConversionFunction or it mi...