diff options
author | Corentin Jabot <corentinjabot@gmail.com> | 2022-01-27 13:55:08 +0100 |
---|---|---|
committer | Corentin Jabot <corentinjabot@gmail.com> | 2023-10-02 14:33:02 +0200 |
commit | af4751738db89a142a8880c782d12d4201b222a8 (patch) | |
tree | b58f2c515b189904f4b598a06f0af0e642343b2c /clang/lib/Sema/SemaChecking.cpp | |
parent | bc7d88faf1a595ab59952a2054418cdd0d9eeee8 (diff) | |
download | llvm-af4751738db89a142a8880c782d12d4201b222a8.zip llvm-af4751738db89a142a8880c782d12d4201b222a8.tar.gz llvm-af4751738db89a142a8880c782d12d4201b222a8.tar.bz2 |
[C++] Implement "Deducing this" (P0847R7)
This patch implements P0847R7 (partially),
CWG2561 and CWG2653.
Reviewed By: aaron.ballman, #clang-language-wg
Differential Revision: https://reviews.llvm.org/D140828
Diffstat (limited to 'clang/lib/Sema/SemaChecking.cpp')
-rw-r--r-- | clang/lib/Sema/SemaChecking.cpp | 49 |
1 files changed, 28 insertions, 21 deletions
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp index 6a3b5fa..0b9bee4 100644 --- a/clang/lib/Sema/SemaChecking.cpp +++ b/clang/lib/Sema/SemaChecking.cpp @@ -126,7 +126,7 @@ static bool checkArgCountAtLeast(Sema &S, CallExpr *Call, return S.Diag(Call->getEndLoc(), diag::err_typecheck_call_too_few_args) << 0 /*function call*/ << MinArgCount << ArgCount - << Call->getSourceRange(); + << /*is non object*/ 0 << Call->getSourceRange(); } /// Checks that a call expression's argument count is at most the desired @@ -139,7 +139,7 @@ static bool checkArgCountAtMost(Sema &S, CallExpr *Call, unsigned MaxArgCount) { return S.Diag(Call->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most) << 0 /*function call*/ << MaxArgCount << ArgCount - << Call->getSourceRange(); + << /*is non object*/ 0 << Call->getSourceRange(); } /// Checks that a call expression's argument count is in the desired range. This @@ -168,7 +168,7 @@ static bool checkArgCount(Sema &S, CallExpr *Call, unsigned DesiredArgCount) { return S.Diag(Range.getBegin(), diag::err_typecheck_call_too_many_args) << 0 /*function call*/ << DesiredArgCount << ArgCount - << Call->getArg(1)->getSourceRange(); + << /*is non object*/ 0 << Call->getArg(1)->getSourceRange(); } static bool convertArgumentToType(Sema &S, Expr *&Value, QualType Ty) { @@ -217,7 +217,7 @@ static bool SemaBuiltinMSVCAnnotation(Sema &S, CallExpr *TheCall) { // We need at least one argument. if (TheCall->getNumArgs() < 1) { S.Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args_at_least) - << 0 << 1 << TheCall->getNumArgs() + << 0 << 1 << TheCall->getNumArgs() << /*is non object*/ 0 << TheCall->getCallee()->getSourceRange(); return true; } @@ -1578,7 +1578,7 @@ static bool SemaOpenCLBuiltinEnqueueKernel(Sema &S, CallExpr *TheCall) { if (NumArgs < 4) { S.Diag(TheCall->getBeginLoc(), diag::err_typecheck_call_too_few_args_at_least) - << 0 << 4 << NumArgs; + << 0 << 4 << NumArgs << /*is non object*/ 0; return true; } @@ -6924,8 +6924,9 @@ void Sema::CheckConstructorCall(FunctionDecl *FDecl, QualType ThisType, Proto->isVariadic() ? VariadicConstructor : VariadicDoesNotApply; auto *Ctor = cast<CXXConstructorDecl>(FDecl); - CheckArgAlignment(Loc, FDecl, "'this'", Context.getPointerType(ThisType), - Context.getPointerType(Ctor->getThisObjectType())); + CheckArgAlignment( + Loc, FDecl, "'this'", Context.getPointerType(ThisType), + Context.getPointerType(Ctor->getFunctionObjectParameterType())); checkCall(FDecl, Proto, /*ThisArg=*/nullptr, Args, /*IsMemberFunction=*/true, Loc, SourceRange(), CallType); @@ -6945,14 +6946,16 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, unsigned NumArgs = TheCall->getNumArgs(); Expr *ImplicitThis = nullptr; - if (IsMemberOperatorCall && !FDecl->isStatic()) { + if (IsMemberOperatorCall && !FDecl->isStatic() && + !FDecl->hasCXXExplicitFunctionObjectParameter()) { // If this is a call to a non-static member operator, hide the first // argument from checkCall. // FIXME: Our choice of AST representation here is less than ideal. ImplicitThis = Args[0]; ++Args; --NumArgs; - } else if (IsMemberFunction && !FDecl->isStatic()) + } else if (IsMemberFunction && !FDecl->isStatic() && + !FDecl->hasCXXExplicitFunctionObjectParameter()) ImplicitThis = cast<CXXMemberCallExpr>(TheCall)->getImplicitObjectArgument(); @@ -6965,8 +6968,8 @@ bool Sema::CheckFunctionCall(FunctionDecl *FDecl, CallExpr *TheCall, ThisType = Context.getPointerType(ThisType); } - QualType ThisTypeFromDecl = - Context.getPointerType(cast<CXXMethodDecl>(FDecl)->getThisObjectType()); + QualType ThisTypeFromDecl = Context.getPointerType( + cast<CXXMethodDecl>(FDecl)->getFunctionObjectParameterType()); CheckArgAlignment(TheCall->getRParenLoc(), FDecl, "'this'", ThisType, ThisTypeFromDecl); @@ -7293,13 +7296,13 @@ ExprResult Sema::BuildAtomicExpr(SourceRange CallRange, SourceRange ExprRange, if (Args.size() < AdjustedNumArgs) { Diag(CallRange.getEnd(), diag::err_typecheck_call_too_few_args) << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size()) - << ExprRange; + << /*is non object*/ 0 << ExprRange; return ExprError(); } else if (Args.size() > AdjustedNumArgs) { Diag(Args[AdjustedNumArgs]->getBeginLoc(), diag::err_typecheck_call_too_many_args) << 0 << AdjustedNumArgs << static_cast<unsigned>(Args.size()) - << ExprRange; + << /*is non object*/ 0 << ExprRange; return ExprError(); } @@ -7662,7 +7665,8 @@ bool Sema::BuiltinWasmRefNullExtern(CallExpr *TheCall) { bool Sema::BuiltinWasmRefNullFunc(CallExpr *TheCall) { if (TheCall->getNumArgs() != 0) { Diag(TheCall->getBeginLoc(), diag::err_typecheck_call_too_many_args) - << 0 /*function call*/ << 0 << TheCall->getNumArgs(); + << 0 /*function call*/ << /*expected*/ 0 << TheCall->getNumArgs() + << /*is non object*/ 0; return true; } @@ -7695,7 +7699,8 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) { // Ensure that we have at least one argument to do type inference from. if (TheCall->getNumArgs() < 1) { Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args_at_least) - << 0 << 1 << TheCall->getNumArgs() << Callee->getSourceRange(); + << 0 << 1 << TheCall->getNumArgs() << /*is non object*/ 0 + << Callee->getSourceRange(); return ExprError(); } @@ -7971,7 +7976,7 @@ Sema::SemaBuiltinAtomicOverloaded(ExprResult TheCallResult) { // have at least that many. if (TheCall->getNumArgs() < 1+NumFixed) { Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args_at_least) - << 0 << 1 + NumFixed << TheCall->getNumArgs() + << 0 << 1 + NumFixed << TheCall->getNumArgs() << /*is non object*/ 0 << Callee->getSourceRange(); return ExprError(); } @@ -8361,7 +8366,8 @@ bool Sema::SemaBuiltinVAStartARMMicrosoft(CallExpr *Call) { if (Call->getNumArgs() < 3) return Diag(Call->getEndLoc(), diag::err_typecheck_call_too_few_args_at_least) - << 0 /*function call*/ << 3 << Call->getNumArgs(); + << 0 /*function call*/ << 3 << Call->getNumArgs() + << /*is non object*/ 0; // Type-check the first argument normally. if (checkBuiltinArgument(*this, Call, 0)) @@ -8622,7 +8628,7 @@ ExprResult Sema::SemaBuiltinShuffleVector(CallExpr *TheCall) { return ExprError(Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args_at_least) << 0 /*function call*/ << 2 << TheCall->getNumArgs() - << TheCall->getSourceRange()); + << /*is non object*/ 0 << TheCall->getSourceRange()); // Determine which of the following types of shufflevector we're checking: // 1) unary, vector mask: (lhs, mask) @@ -8742,7 +8748,8 @@ bool Sema::SemaBuiltinPrefetch(CallExpr *TheCall) { if (NumArgs > 3) return Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most) - << 0 /*function call*/ << 3 << NumArgs << TheCall->getSourceRange(); + << 0 /*function call*/ << 3 << NumArgs << /*is non object*/ 0 + << TheCall->getSourceRange(); // Argument 0 is checked for us and the remaining arguments must be // constant integers. @@ -8881,13 +8888,13 @@ bool Sema::SemaBuiltinOSLogFormat(CallExpr *TheCall) { if (NumArgs < NumRequiredArgs) { return Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_few_args) << 0 /* function call */ << NumRequiredArgs << NumArgs - << TheCall->getSourceRange(); + << /*is non object*/ 0 << TheCall->getSourceRange(); } if (NumArgs >= NumRequiredArgs + 0x100) { return Diag(TheCall->getEndLoc(), diag::err_typecheck_call_too_many_args_at_most) << 0 /* function call */ << (NumRequiredArgs + 0xff) << NumArgs - << TheCall->getSourceRange(); + << /*is non object*/ 0 << TheCall->getSourceRange(); } unsigned i = 0; |