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 Context.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 (Context.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 (Type.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 (getLangOpts().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 (Found.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 ObjC().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 (Context.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 (Cond.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 (Context.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 (Context.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 Context.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 (Context.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 (Cleanup.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 (Cleanup.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 (Base->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 (Context.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 Context.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 (T &&

7211

7212

7213

7214

7217 } else if (T) {

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() || T.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 (T) {

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() || T.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(((TypeName && 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...