diff options
Diffstat (limited to 'gnu/llvm/tools/clang/lib/Sema/SemaLambda.cpp')
| -rw-r--r-- | gnu/llvm/tools/clang/lib/Sema/SemaLambda.cpp | 102 |
1 files changed, 54 insertions, 48 deletions
diff --git a/gnu/llvm/tools/clang/lib/Sema/SemaLambda.cpp b/gnu/llvm/tools/clang/lib/Sema/SemaLambda.cpp index 46f2ba37600..19d2de71972 100644 --- a/gnu/llvm/tools/clang/lib/Sema/SemaLambda.cpp +++ b/gnu/llvm/tools/clang/lib/Sema/SemaLambda.cpp @@ -288,7 +288,9 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC, Normal, DefaultArgument, DataMember, - StaticDataMember + StaticDataMember, + InlineVariable, + VariableTemplate } Kind = Normal; // Default arguments of member function parameters that appear in a class @@ -303,6 +305,14 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC, } else if (VarDecl *Var = dyn_cast<VarDecl>(ManglingContextDecl)) { if (Var->getDeclContext()->isRecord()) Kind = StaticDataMember; + else if (Var->getMostRecentDecl()->isInline()) + Kind = InlineVariable; + else if (Var->getDescribedVarTemplate()) + Kind = VariableTemplate; + else if (auto *VTS = dyn_cast<VarTemplateSpecializationDecl>(Var)) { + if (!VTS->isExplicitSpecialization()) + Kind = VariableTemplate; + } } else if (isa<FieldDecl>(ManglingContextDecl)) { Kind = DataMember; } @@ -343,6 +353,10 @@ Sema::getCurrentMangleNumberContext(const DeclContext *DC, // -- the in-class initializers of class members case DefaultArgument: // -- default arguments appearing in class definitions + case InlineVariable: + // -- the initializers of inline variables + case VariableTemplate: + // -- the initializers of templated variables return &ExprEvalContexts.back().getMangleNumberingContext(Context); } @@ -933,8 +947,8 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, PrevCaptureLoc = C->Loc, ++C) { if (C->Kind == LCK_This || C->Kind == LCK_StarThis) { if (C->Kind == LCK_StarThis) - Diag(C->Loc, !getLangOpts().CPlusPlus1z - ? diag::ext_star_this_lambda_capture_cxx1z + Diag(C->Loc, !getLangOpts().CPlusPlus17 + ? diag::ext_star_this_lambda_capture_cxx17 : diag::warn_cxx14_compat_star_this_lambda_capture); // C++11 [expr.prim.lambda]p8: @@ -948,17 +962,15 @@ void Sema::ActOnStartOfLambdaDefinition(LambdaIntroducer &Intro, continue; } - // C++1z [expr.prim.lambda]p8: - // If a lambda-capture includes a capture-default that is =, each - // simple-capture of that lambda-capture shall be of the form "& - // identifier" or "* this". [ Note: The form [&,this] is redundant but - // accepted for compatibility with ISO C++14. --end note ] - if (Intro.Default == LCD_ByCopy && C->Kind != LCK_StarThis) { - Diag(C->Loc, diag::err_this_capture_with_copy_default) - << FixItHint::CreateRemoval( - SourceRange(getLocForEndOfToken(PrevCaptureLoc), C->Loc)); - continue; - } + // C++2a [expr.prim.lambda]p8: + // If a lambda-capture includes a capture-default that is =, + // each simple-capture of that lambda-capture shall be of the form + // "&identifier", "this", or "* this". [ Note: The form [&,this] is + // redundant but accepted for compatibility with ISO C++14. --end note ] + if (Intro.Default == LCD_ByCopy && C->Kind != LCK_StarThis) + Diag(C->Loc, !getLangOpts().CPlusPlus2a + ? diag::ext_equals_this_lambda_capture_cxx2a + : diag::warn_cxx17_compat_equals_this_lambda_capture); // C++11 [expr.prim.lambda]p12: // If this is captured by a local lambda expression, its nearest @@ -1155,6 +1167,24 @@ void Sema::ActOnLambdaError(SourceLocation StartLoc, Scope *CurScope, PopFunctionScopeInfo(); } +QualType Sema::getLambdaConversionFunctionResultType( + const FunctionProtoType *CallOpProto) { + // The function type inside the pointer type is the same as the call + // operator with some tweaks. The calling convention is the default free + // function convention, and the type qualifications are lost. + const FunctionProtoType::ExtProtoInfo CallOpExtInfo = + CallOpProto->getExtProtoInfo(); + FunctionProtoType::ExtProtoInfo InvokerExtInfo = CallOpExtInfo; + CallingConv CC = Context.getDefaultCallingConvention( + CallOpProto->isVariadic(), /*IsCXXMethod=*/false); + InvokerExtInfo.ExtInfo = InvokerExtInfo.ExtInfo.withCallingConv(CC); + InvokerExtInfo.TypeQuals = 0; + assert(InvokerExtInfo.RefQualifier == RQ_None && + "Lambda's call operator should not have a reference qualifier"); + return Context.getFunctionType(CallOpProto->getReturnType(), + CallOpProto->getParamTypes(), InvokerExtInfo); +} + /// \brief Add a lambda's conversion to function pointer, as described in /// C++11 [expr.prim.lambda]p6. static void addFunctionPointerConversion(Sema &S, @@ -1170,25 +1200,9 @@ static void addFunctionPointerConversion(Sema &S, return; // Add the conversion to function pointer. - const FunctionProtoType *CallOpProto = - CallOperator->getType()->getAs<FunctionProtoType>(); - const FunctionProtoType::ExtProtoInfo CallOpExtInfo = - CallOpProto->getExtProtoInfo(); - QualType PtrToFunctionTy; - QualType InvokerFunctionTy; - { - FunctionProtoType::ExtProtoInfo InvokerExtInfo = CallOpExtInfo; - CallingConv CC = S.Context.getDefaultCallingConvention( - CallOpProto->isVariadic(), /*IsCXXMethod=*/false); - InvokerExtInfo.ExtInfo = InvokerExtInfo.ExtInfo.withCallingConv(CC); - InvokerExtInfo.TypeQuals = 0; - assert(InvokerExtInfo.RefQualifier == RQ_None && - "Lambda's call operator should not have a reference qualifier"); - InvokerFunctionTy = - S.Context.getFunctionType(CallOpProto->getReturnType(), - CallOpProto->getParamTypes(), InvokerExtInfo); - PtrToFunctionTy = S.Context.getPointerType(InvokerFunctionTy); - } + QualType InvokerFunctionTy = S.getLambdaConversionFunctionResultType( + CallOperator->getType()->castAs<FunctionProtoType>()); + QualType PtrToFunctionTy = S.Context.getPointerType(InvokerFunctionTy); // Create the type of the conversion function. FunctionProtoType::ExtProtoInfo ConvExtInfo( @@ -1276,7 +1290,7 @@ static void addFunctionPointerConversion(Sema &S, ConvTy, ConvTSI, /*isInline=*/true, /*isExplicit=*/false, - /*isConstexpr=*/S.getLangOpts().CPlusPlus1z, + /*isConstexpr=*/S.getLangOpts().CPlusPlus17, CallOperator->getBody()->getLocEnd()); Conversion->setAccess(AS_public); Conversion->setImplicit(true); @@ -1345,19 +1359,8 @@ static void addBlockPointerConversion(Sema &S, SourceRange IntroducerRange, CXXRecordDecl *Class, CXXMethodDecl *CallOperator) { - const FunctionProtoType *Proto = - CallOperator->getType()->getAs<FunctionProtoType>(); - - // The function type inside the block pointer type is the same as the call - // operator with some tweaks. The calling convention is the default free - // function convention, and the type qualifications are lost. - FunctionProtoType::ExtProtoInfo BlockEPI = Proto->getExtProtoInfo(); - BlockEPI.ExtInfo = - BlockEPI.ExtInfo.withCallingConv(S.Context.getDefaultCallingConvention( - Proto->isVariadic(), /*IsCXXMethod=*/false)); - BlockEPI.TypeQuals = 0; - QualType FunctionTy = S.Context.getFunctionType( - Proto->getReturnType(), Proto->getParamTypes(), BlockEPI); + QualType FunctionTy = S.getLambdaConversionFunctionResultType( + CallOperator->getType()->castAs<FunctionProtoType>()); QualType BlockPtrTy = S.Context.getBlockPointerType(FunctionTy); FunctionProtoType::ExtProtoInfo ConversionEPI( @@ -1469,6 +1472,9 @@ void Sema::DiagnoseUnusedLambdaCapture(const LambdaScopeInfo::Capture &From) { if (CaptureHasSideEffects(From)) return; + if (From.isVLATypeCapture()) + return; + auto diag = Diag(From.getLocation(), diag::warn_unused_lambda_capture); if (From.isThisCapture()) diag << "'this'"; @@ -1596,7 +1602,7 @@ ExprResult Sema::BuildLambdaExpr(SourceLocation StartLoc, SourceLocation EndLoc, // If the lambda expression's call operator is not explicitly marked constexpr // and we are not in a dependent context, analyze the call operator to infer // its constexpr-ness, suppressing diagnostics while doing so. - if (getLangOpts().CPlusPlus1z && !CallOperator->isInvalidDecl() && + if (getLangOpts().CPlusPlus17 && !CallOperator->isInvalidDecl() && !CallOperator->isConstexpr() && !isa<CoroutineBodyStmt>(CallOperator->getBody()) && !Class->getDeclContext()->isDependentContext()) { |
