@@ -2220,6 +2220,99 @@ static bool BuiltinCountZeroBitsGeneric(Sema &S, CallExpr *TheCall) {
2220
2220
return false;
2221
2221
}
2222
2222
2223
+ static ExprResult BuiltinInvoke(Sema &S, CallExpr *TheCall) {
2224
+ SourceLocation Loc = TheCall->getBeginLoc();
2225
+ MutableArrayRef Args(TheCall->getArgs(), TheCall->getNumArgs());
2226
+ assert(llvm::none_of(Args, [](Expr *Arg) { return Arg->isTypeDependent(); }));
2227
+
2228
+ if (Args.size() == 0) {
2229
+ S.Diag(TheCall->getBeginLoc(),
2230
+ diag::err_typecheck_call_too_few_args_at_least)
2231
+ << /*callee_type=*/0 << /*min_arg_count=*/1 << /*actual_arg_count=*/0
2232
+ << /*is_non_object=*/0 << TheCall->getSourceRange();
2233
+ return ExprError();
2234
+ }
2235
+
2236
+ QualType FuncT = Args[0]->getType();
2237
+
2238
+ if (const auto *MPT = FuncT->getAs<MemberPointerType>()) {
2239
+ if (Args.size() < 2) {
2240
+ S.Diag(TheCall->getBeginLoc(),
2241
+ diag::err_typecheck_call_too_few_args_at_least)
2242
+ << /*callee_type=*/0 << /*min_arg_count=*/2 << /*actual_arg_count=*/1
2243
+ << /*is_non_object=*/0 << TheCall->getSourceRange();
2244
+ return ExprError();
2245
+ }
2246
+
2247
+ const Type *MemPtrClass = MPT->getQualifier()->getAsType();
2248
+ QualType ObjectT = Args[1]->getType();
2249
+
2250
+ if (MPT->isMemberDataPointer() && S.checkArgCount(TheCall, 2))
2251
+ return ExprError();
2252
+
2253
+ ExprResult ObjectArg = [&]() -> ExprResult {
2254
+ // (1.1): (t1.*f)(t2, ..., tN) when f is a pointer to a member function of
2255
+ // a class T and is_same_v<T, remove_cvref_t<decltype(t1)>> ||
2256
+ // is_base_of_v<T, remove_cvref_t<decltype(t1)>> is true;
2257
+ // (1.4): t1.*f when N=1 and f is a pointer to data member of a class T
2258
+ // and is_same_v<T, remove_cvref_t<decltype(t1)>> ||
2259
+ // is_base_of_v<T, remove_cvref_t<decltype(t1)>> is true;
2260
+ if (S.Context.hasSameType(QualType(MemPtrClass, 0),
2261
+ S.BuiltinRemoveCVRef(ObjectT, Loc)) ||
2262
+ S.BuiltinIsBaseOf(Args[1]->getBeginLoc(), QualType(MemPtrClass, 0),
2263
+ S.BuiltinRemoveCVRef(ObjectT, Loc))) {
2264
+ return Args[1];
2265
+ }
2266
+
2267
+ // (t1.get().*f)(t2, ..., tN) when f is a pointer to a member function of
2268
+ // a class T and remove_cvref_t<decltype(t1)> is a specialization of
2269
+ // reference_wrapper;
2270
+ if (const auto *RD = ObjectT->getAsCXXRecordDecl()) {
2271
+ if (RD->isInStdNamespace() &&
2272
+ RD->getDeclName().getAsString() == "reference_wrapper") {
2273
+ CXXScopeSpec SS;
2274
+ IdentifierInfo *GetName = &S.Context.Idents.get("get");
2275
+ UnqualifiedId GetID;
2276
+ GetID.setIdentifier(GetName, Loc);
2277
+
2278
+ ExprResult MemExpr = S.ActOnMemberAccessExpr(
2279
+ S.getCurScope(), Args[1], Loc, tok::period, SS,
2280
+ /*TemplateKWLoc=*/SourceLocation(), GetID, nullptr);
2281
+
2282
+ if (MemExpr.isInvalid())
2283
+ return ExprError();
2284
+
2285
+ return S.ActOnCallExpr(S.getCurScope(), MemExpr.get(), Loc, {}, Loc);
2286
+ }
2287
+ }
2288
+
2289
+ // ((*t1).*f)(t2, ..., tN) when f is a pointer to a member function of a
2290
+ // class T and t1 does not satisfy the previous two items;
2291
+
2292
+ return S.ActOnUnaryOp(S.getCurScope(), Loc, tok::star, Args[1]);
2293
+ }();
2294
+
2295
+ if (ObjectArg.isInvalid())
2296
+ return ExprError();
2297
+
2298
+ ExprResult BinOp = S.ActOnBinOp(S.getCurScope(), TheCall->getBeginLoc(),
2299
+ tok::periodstar, ObjectArg.get(), Args[0]);
2300
+ if (BinOp.isInvalid())
2301
+ return ExprError();
2302
+
2303
+ if (MPT->isMemberDataPointer())
2304
+ return BinOp;
2305
+
2306
+ auto *MemCall = new (S.Context)
2307
+ ParenExpr(SourceLocation(), SourceLocation(), BinOp.get());
2308
+
2309
+ return S.ActOnCallExpr(S.getCurScope(), MemCall, TheCall->getBeginLoc(),
2310
+ Args.drop_front(2), TheCall->getRParenLoc());
2311
+ }
2312
+ return S.ActOnCallExpr(S.getCurScope(), Args.front(), TheCall->getBeginLoc(),
2313
+ Args.drop_front(), TheCall->getRParenLoc());
2314
+ }
2315
+
2223
2316
ExprResult
2224
2317
Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
2225
2318
CallExpr *TheCall) {
@@ -2369,7 +2462,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
2369
2462
// TheCall will be freed by the smart pointer here, but that's fine, since
2370
2463
// BuiltinShuffleVector guts it, but then doesn't release it.
2371
2464
case Builtin::BI__builtin_invoke:
2372
- return BuiltinInvoke(TheCall);
2465
+ return BuiltinInvoke(*this, TheCall);
2373
2466
case Builtin::BI__builtin_prefetch:
2374
2467
if (BuiltinPrefetch(TheCall))
2375
2468
return ExprError();
@@ -5408,99 +5501,6 @@ ExprResult Sema::ConvertVectorExpr(Expr *E, TypeSourceInfo *TInfo,
5408
5501
RParenLoc, CurFPFeatureOverrides());
5409
5502
}
5410
5503
5411
- ExprResult Sema::BuiltinInvoke(CallExpr *TheCall) {
5412
- SourceLocation Loc = TheCall->getBeginLoc();
5413
- auto Args = MutableArrayRef(TheCall->getArgs(), TheCall->getNumArgs());
5414
- assert(llvm::none_of(Args,
5415
- [](Expr *Arg) { return Arg->isTypeDependent(); }));
5416
-
5417
- if (Args.size() == 0) {
5418
- Diag(TheCall->getBeginLoc(), diag::err_typecheck_call_too_few_args_at_least)
5419
- << /*callee_type=*/0 << /*min_arg_count=*/1 << /*actual_arg_count=*/0
5420
- << /*is_non_object=*/0 << TheCall->getSourceRange();
5421
- return ExprError();
5422
- }
5423
-
5424
- auto FuncT = Args[0]->getType();
5425
-
5426
- if (auto *MPT = FuncT->getAs<MemberPointerType>()) {
5427
- if (Args.size() < 2) {
5428
- Diag(TheCall->getBeginLoc(),
5429
- diag::err_typecheck_call_too_few_args_at_least)
5430
- << /*callee_type=*/0 << /*min_arg_count=*/2 << /*actual_arg_count=*/1
5431
- << /*is_non_object=*/0 << TheCall->getSourceRange();
5432
- return ExprError();
5433
- }
5434
-
5435
- auto *MemPtrClass = MPT->getQualifier()->getAsType();
5436
- auto ObjectT = Args[1]->getType();
5437
-
5438
- if (MPT->isMemberDataPointer() && checkArgCount(TheCall, 2))
5439
- return ExprError();
5440
-
5441
- ExprResult ObjectArg = [&]() -> ExprResult {
5442
- // (1.1): (t1.*f)(t2, …, tN) when f is a pointer to a member function of a
5443
- // class T and is_same_v<T, remove_cvref_t<decltype(t1)>> ||
5444
- // is_base_of_v<T, remove_cvref_t<decltype(t1)>> is true;
5445
- // (1.4): t1.*f when N=1 and f is a pointer to data member of a class T
5446
- // and is_same_v<T, remove_cvref_t<decltype(t1)>> ||
5447
- // is_base_of_v<T, remove_cvref_t<decltype(t1)>> is true;
5448
- if (Context.hasSameType(QualType(MemPtrClass, 0),
5449
- BuiltinRemoveCVRef(ObjectT, Loc)) ||
5450
- BuiltinIsBaseOf(Args[1]->getBeginLoc(), QualType(MemPtrClass, 0),
5451
- BuiltinRemoveCVRef(ObjectT, Loc))) {
5452
- return Args[1];
5453
- }
5454
-
5455
- // (t1.get().*f)(t2, …, tN) when f is a pointer to a member function of
5456
- // a class T and remove_cvref_t<decltype(t1)> is a specialization of
5457
- // reference_wrapper;
5458
- if (auto *RD = ObjectT->getAsCXXRecordDecl()) {
5459
- if (RD->isInStdNamespace() &&
5460
- RD->getDeclName().getAsString() == "reference_wrapper") {
5461
- CXXScopeSpec SS;
5462
- IdentifierInfo *GetName = &Context.Idents.get("get");
5463
- UnqualifiedId GetID;
5464
- GetID.setIdentifier(GetName, Loc);
5465
-
5466
- auto MemExpr = ActOnMemberAccessExpr(
5467
- getCurScope(), Args[1], Loc, tok::period, SS,
5468
- /*TemplateKWLoc=*/SourceLocation(), GetID, nullptr);
5469
-
5470
- if (MemExpr.isInvalid())
5471
- return ExprError();
5472
-
5473
- return ActOnCallExpr(getCurScope(), MemExpr.get(), Loc, {}, Loc);
5474
- }
5475
- }
5476
-
5477
- // ((*t1).*f)(t2, …, tN) when f is a pointer to a member function of a
5478
- // class T and t1 does not satisfy the previous two items;
5479
-
5480
- return ActOnUnaryOp(getCurScope(), Loc, tok::star, Args[1]);
5481
- }();
5482
-
5483
- if (ObjectArg.isInvalid())
5484
- return ExprError();
5485
-
5486
- auto BinOp = ActOnBinOp(getCurScope(), TheCall->getBeginLoc(),
5487
- tok::periodstar, ObjectArg.get(), Args[0]);
5488
- if (BinOp.isInvalid())
5489
- return ExprError();
5490
-
5491
- if (MPT->isMemberDataPointer())
5492
- return BinOp;
5493
-
5494
- auto *MemCall = new (Context)
5495
- ParenExpr(SourceLocation(), SourceLocation(), BinOp.get());
5496
-
5497
- return ActOnCallExpr(getCurScope(), MemCall, TheCall->getBeginLoc(),
5498
- Args.drop_front(2), TheCall->getRParenLoc());
5499
- }
5500
- return ActOnCallExpr(getCurScope(), Args.front(), TheCall->getBeginLoc(),
5501
- Args.drop_front(), TheCall->getRParenLoc());
5502
- }
5503
-
5504
5504
bool Sema::BuiltinPrefetch(CallExpr *TheCall) {
5505
5505
unsigned NumArgs = TheCall->getNumArgs();
5506
5506
0 commit comments