cor3ntin updated this revision to Diff 423653.
cor3ntin added a comment.

Remove some whitespace only changes.


Repository:
  rG LLVM Github Monorepo

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D124012/new/

https://reviews.llvm.org/D124012

Files:
  clang/include/clang/Sema/Sema.h
  clang/lib/Sema/SemaLambda.cpp
  clang/lib/Sema/TreeTransform.h
  clang/test/SemaCXX/lambda-capture-type-deduction.cpp

Index: clang/test/SemaCXX/lambda-capture-type-deduction.cpp
===================================================================
--- clang/test/SemaCXX/lambda-capture-type-deduction.cpp
+++ clang/test/SemaCXX/lambda-capture-type-deduction.cpp
@@ -163,6 +163,35 @@
   [&]() requires is_same<decltype(u), T> {}();
 }
 
+template <typename T>
+void dependent_init_capture(T x = 0) {
+  [ y = x + 1, x ]() mutable -> decltype(y + x) requires(is_same<decltype((y)), int &> && is_same<decltype((x)), int &>) {
+    return y;
+  }
+  ();
+  [ y = x + 1, x ]() -> decltype(y + x) requires(is_same<decltype((y)), const int &> && is_same<decltype((x)), const int &>) {
+    return y;
+  }
+  ();
+}
+
+template <typename T, typename...>
+struct extract_type {
+  using type = T;
+};
+
+template <typename... T>
+void dependent_variadic_capture(T... x) {
+  [... y = x, x... ](auto...) mutable -> typename extract_type<decltype(y)...>::type requires((is_same<decltype((y)), int &> && ...) && (is_same<decltype((x)), int &> && ...)) {
+    return 0;
+  }
+  (x...);
+  [... y = x, x... ](auto...) -> typename extract_type<decltype(y)...>::type requires((is_same<decltype((y)), const int &> && ...) && (is_same<decltype((x)), const int &> && ...)) {
+    return 0;
+  }
+  (x...);
+}
+
 void test_dependent() {
   int v   = 0;
   int & r = v;
@@ -170,6 +199,8 @@
   dependent<int&>(v);
   dependent<int&>(r);
   dependent<const int&>(cr);
+  dependent_init_capture(0);
+  dependent_variadic_capture(1, 2, 3, 4);
 }
 
 void test_CWG2569_tpl(auto a) {
Index: clang/lib/Sema/TreeTransform.h
===================================================================
--- clang/lib/Sema/TreeTransform.h
+++ clang/lib/Sema/TreeTransform.h
@@ -12883,9 +12883,8 @@
       /*ListInitialization=*/LParenLoc.isInvalid());
 }
 
-template<typename Derived>
-ExprResult
-TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
+template <typename Derived>
+ExprResult TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
   // Transform any init-capture expressions before entering the scope of the
   // lambda body, because they are not semantically within that scope.
   typedef std::pair<ExprResult, QualType> InitCaptureInfoTy;
@@ -12943,9 +12942,8 @@
           ExpansionTL.getTypePtr()->getNumExpansions();
       Optional<unsigned> NumExpansions = OrigNumExpansions;
       if (getDerived().TryExpandParameterPacks(
-              ExpansionTL.getEllipsisLoc(),
-              OldVD->getInit()->getSourceRange(), Unexpanded, Expand,
-              RetainExpansion, NumExpansions))
+              ExpansionTL.getEllipsisLoc(), OldVD->getInit()->getSourceRange(),
+              Unexpanded, Expand, RetainExpansion, NumExpansions))
         return ExprError();
       if (Expand) {
         for (unsigned I = 0; I != *NumExpansions; ++I) {
@@ -12966,44 +12964,6 @@
   LambdaScopeInfo *LSI = getSema().PushLambdaScope();
   Sema::FunctionScopeRAII FuncScopeCleanup(getSema());
 
-  // Transform the template parameters, and add them to the current
-  // instantiation scope. The null case is handled correctly.
-  auto TPL = getDerived().TransformTemplateParameterList(
-      E->getTemplateParameterList());
-  LSI->GLTemplateParameterList = TPL;
-
-  // Transform the type of the original lambda's call operator.
-  // The transformation MUST be done in the CurrentInstantiationScope since
-  // it introduces a mapping of the original to the newly created
-  // transformed parameters.
-  TypeSourceInfo *NewCallOpTSI = nullptr;
-  {
-    TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo();
-    FunctionProtoTypeLoc OldCallOpFPTL =
-        OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>();
-
-    TypeLocBuilder NewCallOpTLBuilder;
-    SmallVector<QualType, 4> ExceptionStorage;
-    TreeTransform *This = this; // Work around gcc.gnu.org/PR56135.
-    QualType NewCallOpType = TransformFunctionProtoType(
-        NewCallOpTLBuilder, OldCallOpFPTL, nullptr, Qualifiers(),
-        [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
-          return This->TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI,
-                                              ExceptionStorage, Changed);
-        });
-    if (NewCallOpType.isNull())
-      return ExprError();
-    NewCallOpTSI = NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context,
-                                                        NewCallOpType);
-  }
-
-  // Transform the trailing requires clause
-  ExprResult NewTrailingRequiresClause;
-  if (Expr *TRC = E->getCallOperator()->getTrailingRequiresClause())
-    // FIXME: Concepts: Substitution into requires clause should only happen
-    //                  when checking satisfaction.
-    NewTrailingRequiresClause = getDerived().TransformExpr(TRC);
-
   // Create the local class that will describe the lambda.
 
   // FIXME: DependencyKind below is wrong when substituting inside a templated
@@ -13019,10 +12979,8 @@
     DependencyKind = CXXRecordDecl::LDK_NeverDependent;
 
   CXXRecordDecl *OldClass = E->getLambdaClass();
-  CXXRecordDecl *Class =
-      getSema().createLambdaClosureType(E->getIntroducerRange(), NewCallOpTSI,
-                                        DependencyKind, E->getCaptureDefault());
-
+  CXXRecordDecl *Class = getSema().createLambdaClosureType(
+      E->getIntroducerRange(), nullptr, DependencyKind, E->getCaptureDefault());
   getDerived().transformedLocalDecl(OldClass, {Class});
 
   Optional<std::tuple<bool, unsigned, unsigned, Decl *>> Mangling;
@@ -13032,40 +12990,24 @@
                                OldClass->getDeviceLambdaManglingNumber(),
                                OldClass->getLambdaContextDecl());
 
-  // Build the call operator.
-  CXXMethodDecl *NewCallOperator = getSema().startLambdaDefinition(
-      Class, E->getIntroducerRange(), NewCallOpTSI,
-      E->getCallOperator()->getEndLoc(),
-      NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(),
-      E->getCallOperator()->getConstexprKind(),
-      NewTrailingRequiresClause.get());
-
-  LSI->CallOperator = NewCallOperator;
-
-  getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
-  getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
+  CXXMethodDecl *NewCallOperator =
+      getSema().CreateLambdaCallOperator(E->getIntroducerRange(), Class);
+  NewCallOperator->setLexicalDeclContext(getSema().CurContext);
 
-  // Number the lambda for linkage purposes if necessary.
-  getSema().handleLambdaNumbering(Class, NewCallOperator, Mangling);
+  // Enter the scope of the lambda.
+  getSema().buildLambdaScope(LSI, NewCallOperator, E->getIntroducerRange(),
+                             E->getCaptureDefault(), E->getCaptureDefaultLoc(),
+                             E->hasExplicitParameters(), E->isMutable());
 
   // Introduce the context of the call operator.
   Sema::ContextRAII SavedContext(getSema(), NewCallOperator,
-                                 /*NewThisContext*/false);
-
-  // Enter the scope of the lambda.
-  getSema().buildLambdaScope(LSI, NewCallOperator,
-                             E->getIntroducerRange(),
-                             E->getCaptureDefault(),
-                             E->getCaptureDefaultLoc(),
-                             E->hasExplicitParameters(),
-                             E->hasExplicitResultType(),
-                             E->isMutable());
+                                 /*NewThisContext*/ false);
 
   bool Invalid = false;
 
   // Transform captures.
   for (LambdaExpr::capture_iterator C = E->capture_begin(),
-                                 CEnd = E->capture_end();
+                                    CEnd = E->capture_end();
        C != CEnd; ++C) {
     // When we hit the first implicit capture, tell Sema that we've finished
     // the list of explicit captures.
@@ -13089,7 +13031,7 @@
       TransformedInitCapture &NewC = InitCaptures[C - E->capture_begin()];
 
       VarDecl *OldVD = C->getCapturedVar();
-      llvm::SmallVector<Decl*, 4> NewVDs;
+      llvm::SmallVector<Decl *, 4> NewVDs;
 
       for (InitCaptureInfoTy &Info : NewC.Expansions) {
         ExprResult Init = Info.first;
@@ -13120,22 +13062,19 @@
     assert(C->capturesVariable() && "unexpected kind of lambda capture");
 
     // Determine the capture kind for Sema.
-    Sema::TryCaptureKind Kind
-      = C->isImplicit()? Sema::TryCapture_Implicit
-                       : C->getCaptureKind() == LCK_ByCopy
-                           ? Sema::TryCapture_ExplicitByVal
-                           : Sema::TryCapture_ExplicitByRef;
+    Sema::TryCaptureKind Kind = C->isImplicit() ? Sema::TryCapture_Implicit
+                                : C->getCaptureKind() == LCK_ByCopy
+                                    ? Sema::TryCapture_ExplicitByVal
+                                    : Sema::TryCapture_ExplicitByRef;
     SourceLocation EllipsisLoc;
     if (C->isPackExpansion()) {
       UnexpandedParameterPack Unexpanded(C->getCapturedVar(), C->getLocation());
       bool ShouldExpand = false;
       bool RetainExpansion = false;
       Optional<unsigned> NumExpansions;
-      if (getDerived().TryExpandParameterPacks(C->getEllipsisLoc(),
-                                               C->getLocation(),
-                                               Unexpanded,
-                                               ShouldExpand, RetainExpansion,
-                                               NumExpansions)) {
+      if (getDerived().TryExpandParameterPacks(
+              C->getEllipsisLoc(), C->getLocation(), Unexpanded, ShouldExpand,
+              RetainExpansion, NumExpansions)) {
         Invalid = true;
         continue;
       }
@@ -13147,9 +13086,8 @@
         VarDecl *Pack = C->getCapturedVar();
         for (unsigned I = 0; I != *NumExpansions; ++I) {
           Sema::ArgumentPackSubstitutionIndexRAII SubstIndex(getSema(), I);
-          VarDecl *CapturedVar
-            = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
-                                                               Pack));
+          VarDecl *CapturedVar = cast_or_null<VarDecl>(
+              getDerived().TransformDecl(C->getLocation(), Pack));
           if (!CapturedVar) {
             Invalid = true;
             continue;
@@ -13168,9 +13106,8 @@
     }
 
     // Transform the captured variable.
-    VarDecl *CapturedVar
-      = cast_or_null<VarDecl>(getDerived().TransformDecl(C->getLocation(),
-                                                         C->getCapturedVar()));
+    VarDecl *CapturedVar = cast_or_null<VarDecl>(
+        getDerived().TransformDecl(C->getLocation(), C->getCapturedVar()));
     if (!CapturedVar || CapturedVar->isInvalidDecl()) {
       Invalid = true;
       continue;
@@ -13182,6 +13119,60 @@
   }
   getSema().finishLambdaExplicitCaptures(LSI);
 
+  // Transform the template parameters, and add them to the current
+  // instantiation scope. The null case is handled correctly.
+  auto TPL = getDerived().TransformTemplateParameterList(
+      E->getTemplateParameterList());
+  LSI->GLTemplateParameterList = TPL;
+
+  // Transform the type of the original lambda's call operator.
+  // The transformation MUST be done in the CurrentInstantiationScope since
+  // it introduces a mapping of the original to the newly created
+  // transformed parameters.
+  TypeSourceInfo *NewCallOpTSI = nullptr;
+  {
+    TypeSourceInfo *OldCallOpTSI = E->getCallOperator()->getTypeSourceInfo();
+    FunctionProtoTypeLoc OldCallOpFPTL =
+        OldCallOpTSI->getTypeLoc().getAs<FunctionProtoTypeLoc>();
+
+    TypeLocBuilder NewCallOpTLBuilder;
+    SmallVector<QualType, 4> ExceptionStorage;
+    TreeTransform *This = this; // Work around gcc.gnu.org/PR56135.
+    QualType NewCallOpType = TransformFunctionProtoType(
+        NewCallOpTLBuilder, OldCallOpFPTL, nullptr, Qualifiers(),
+        [&](FunctionProtoType::ExceptionSpecInfo &ESI, bool &Changed) {
+          return This->TransformExceptionSpec(OldCallOpFPTL.getBeginLoc(), ESI,
+                                              ExceptionStorage, Changed);
+        });
+    if (NewCallOpType.isNull())
+      return ExprError();
+    NewCallOpTSI =
+        NewCallOpTLBuilder.getTypeSourceInfo(getSema().Context, NewCallOpType);
+  }
+
+  // Transform the trailing requires clause
+  ExprResult NewTrailingRequiresClause;
+  if (Expr *TRC = E->getCallOperator()->getTrailingRequiresClause())
+    // FIXME: Concepts: Substitution into requires clause should only happen
+    //                  when checking satisfaction.
+    NewTrailingRequiresClause = getDerived().TransformExpr(TRC);
+
+  getSema().buildCompleteLambdaCallOperator(
+      NewCallOperator, E->getCallOperator()->getLocation(),
+      NewTrailingRequiresClause.get(), NewCallOpTSI,
+      E->getCallOperator()->getConstexprKind(),
+      NewCallOpTSI->getTypeLoc().castAs<FunctionProtoTypeLoc>().getParams(),
+      E->hasExplicitResultType());
+
+  getDerived().transformAttrs(E->getCallOperator(), NewCallOperator);
+  getDerived().transformedLocalDecl(E->getCallOperator(), {NewCallOperator});
+
+  {
+    // Number the lambda for linkage purposes if necessary.
+    Sema::ContextRAII ManglingContext(getSema(), Class->getDeclContext());
+    getSema().handleLambdaNumbering(Class, NewCallOperator, Mangling);
+  }
+
   // FIXME: Sema's lambda-building mechanism expects us to push an expression
   // evaluation context even if we're not transforming the function body.
   getSema().PushExpressionEvaluationContext(
Index: clang/lib/Sema/SemaLambda.cpp
===================================================================
--- clang/lib/Sema/SemaLambda.cpp
+++ clang/lib/Sema/SemaLambda.cpp
@@ -540,11 +540,9 @@
                             SourceRange IntroducerRange,
                             LambdaCaptureDefault CaptureDefault,
                             SourceLocation CaptureDefaultLoc,
-                            bool ExplicitParams, bool ExplicitResultType,
-                            bool Mutable) {
+                            bool ExplicitParams, bool Mutable) {
   buildLambdaScopeCaptures(LSI, CallOperator, IntroducerRange, CaptureDefault,
                            CaptureDefaultLoc, ExplicitParams, Mutable);
-  buildLambdaScopeReturnType(*this, LSI, CallOperator, ExplicitResultType);
 }
 
 void Sema::finishLambdaExplicitCaptures(LambdaScopeInfo *LSI) {
@@ -953,28 +951,74 @@
   return MethodTyInfo;
 }
 
-static CXXMethodDecl *CreateMethod(Sema &S, SourceRange IntroducerRange,
-                                   CXXRecordDecl *Class) {
+CXXMethodDecl *Sema::CreateLambdaCallOperator(SourceRange IntroducerRange,
+                                              CXXRecordDecl *Class) {
+
   // C++11 [expr.prim.lambda]p5:
   //   The closure type for a lambda-expression has a public inline function
   //   call operator (13.5.4) whose parameters and return type are described
   //   by the lambda-expression's parameter-declaration-clause and
   //   trailing-return-type respectively.
   DeclarationName MethodName =
-      S.Context.DeclarationNames.getCXXOperatorName(OO_Call);
+      Context.DeclarationNames.getCXXOperatorName(OO_Call);
   DeclarationNameLoc MethodNameLoc =
       DeclarationNameLoc::makeCXXOperatorNameLoc(IntroducerRange.getBegin());
   CXXMethodDecl *Method = CXXMethodDecl::Create(
-      S.Context, Class, SourceLocation(),
+      Context, Class, SourceLocation(),
       DeclarationNameInfo(MethodName, IntroducerRange.getBegin(),
                           MethodNameLoc),
-      QualType(), nullptr, SC_None, S.getCurFPFeatures().isFPConstrained(),
+      QualType(), nullptr, SC_None, getCurFPFeatures().isFPConstrained(),
       /*isInline=*/true, ConstexprSpecKind::Unspecified, SourceLocation(),
       nullptr);
   Method->setAccess(AS_public);
   return Method;
 }
 
+void Sema::buildCompleteLambdaCallOperator(
+    CXXMethodDecl *Method, SourceLocation Loc, Expr *TrailingRequiresClause,
+    TypeSourceInfo *MethodTyInfo, ConstexprSpecKind ConstexprKind,
+    ArrayRef<ParmVarDecl *> Params, bool HasExplicitResultType) {
+
+  LambdaScopeInfo *const LSI = getCurrentLambdaScopeUnsafe(*this);
+
+  if (TrailingRequiresClause)
+    Method->setTrailingRequiresClause(TrailingRequiresClause);
+
+  TemplateParameterList *TemplateParams =
+      getGenericLambdaTemplateParameterList(LSI, *this);
+
+  auto DC = Method->getLexicalDeclContext();
+  Method->setLexicalDeclContext(LSI->Lambda);
+  if (TemplateParams) {
+    FunctionTemplateDecl *const TemplateMethod = FunctionTemplateDecl::Create(
+        Context, LSI->Lambda, Method->getLocation(), Method->getDeclName(),
+        TemplateParams, Method);
+    TemplateMethod->setAccess(AS_public);
+    Method->setDescribedFunctionTemplate(TemplateMethod);
+    LSI->Lambda->addDecl(TemplateMethod);
+    TemplateMethod->setLexicalDeclContext(DC);
+  } else {
+    LSI->Lambda->addDecl(Method);
+  }
+  LSI->Lambda->setLambdaIsGeneric(TemplateParams);
+  LSI->Lambda->setLambdaTypeInfo(MethodTyInfo);
+
+  Method->setLexicalDeclContext(DC);
+  Method->setLocation(Loc);
+  Method->setTypeSourceInfo(MethodTyInfo);
+  Method->setType(buildTypeForLambdaCallOperator(*this, LSI->Lambda,
+                                                 TemplateParams, MethodTyInfo));
+  Method->setConstexprKind(ConstexprKind);
+  if (!Params.empty()) {
+    CheckParmsForFunctionDef(Params, /*CheckParameterNames=*/false);
+    Method->setParams(Params);
+    for (auto P : Method->parameters())
+      P->setOwningFunction(Method);
+  }
+
+  buildLambdaScopeReturnType(*this, LSI, Method, HasExplicitResultType);
+}
+
 void Sema::ActOnLambdaIntroducer(LambdaIntroducer &Intro, Scope *CurrentScope) {
 
   LambdaScopeInfo *const LSI = getCurLambda();
@@ -1016,7 +1060,7 @@
   //   by the lambda-expression's parameter-declaration-clause and
   //   trailing-return-type respectively.
 
-  CXXMethodDecl *Method = CreateMethod(*this, Intro.Range, Class);
+  CXXMethodDecl *Method = CreateLambdaCallOperator(Intro.Range, Class);
   LSI->CallOperator = Method;
   Method->setLexicalDeclContext(CurContext);
 
@@ -1312,40 +1356,9 @@
   CXXRecordDecl *Class = LSI->Lambda;
   CXXMethodDecl *Method = LSI->CallOperator;
 
-  if (auto *C = ParamInfo.getTrailingRequiresClause())
-    Method->setTrailingRequiresClause(C);
-
-  TemplateParameterList *TemplateParams =
-      getGenericLambdaTemplateParameterList(LSI, *this);
-
-  auto DC = Method->getLexicalDeclContext();
-  Method->setLexicalDeclContext(Class);
-  if (TemplateParams) {
-    FunctionTemplateDecl *const TemplateMethod = FunctionTemplateDecl::Create(
-        Context, Class, Method->getLocation(), Method->getDeclName(),
-        TemplateParams, Method);
-    TemplateMethod->setAccess(AS_public);
-    Method->setDescribedFunctionTemplate(TemplateMethod);
-    Class->addDecl(TemplateMethod);
-    TemplateMethod->setLexicalDeclContext(DC);
-  } else {
-    Class->addDecl(Method);
-  }
-  Method->setLexicalDeclContext(DC);
-  Class->setLambdaIsGeneric(TemplateParams);
-
   TypeSourceInfo *MethodTyInfo = getLambdaType(
       *this, Intro, ParamInfo, getCurScope(), TypeLoc, ExplicitResultType);
 
-  Class->setLambdaTypeInfo(MethodTyInfo);
-  Method->setInnerLocStart(LambdaLoc);
-  Method->setLocation(Intro.Range.getBegin());
-  Method->setTypeSourceInfo(MethodTyInfo);
-  Method->setType(buildTypeForLambdaCallOperator(*this, Class, TemplateParams,
-                                                 MethodTyInfo));
-  Method->setConstexprKind(ParamInfo.getDeclSpec().getConstexprSpecifier());
-  buildLambdaScopeReturnType(*this, LSI, Method, ExplicitResultType);
-
   LSI->ExplicitParams = ParamInfo.getNumTypeObjects() != 0;
 
   if (ParamInfo.isFunctionDeclarator() != 0 &&
@@ -1359,14 +1372,15 @@
     }
   }
 
-  ContextRAII ManglingContext(*this, Class->getDeclContext());
+  Method->setInnerLocStart(LambdaLoc);
+  buildCompleteLambdaCallOperator(
+      Method, Intro.Range.getBegin(), ParamInfo.getTrailingRequiresClause(),
+      MethodTyInfo, ParamInfo.getDeclSpec().getConstexprSpecifier(), Params,
+      ExplicitResultType);
 
-  CheckParmsForFunctionDef(Params, /*CheckParameterNames=*/false);
+  ContextRAII ManglingContext(*this, Class->getDeclContext());
 
-  if (LSI->ExplicitParams) {
-    Method->setParams(Params);
-    CheckCXXDefaultArguments(Method);
-  }
+  CheckCXXDefaultArguments(Method);
 
   // This represents the function body for the lambda function, check if we
   // have to apply optnone due to a pragma.
Index: clang/include/clang/Sema/Sema.h
===================================================================
--- clang/include/clang/Sema/Sema.h
+++ clang/include/clang/Sema/Sema.h
@@ -6849,9 +6849,15 @@
                         LambdaCaptureDefault CaptureDefault,
                         SourceLocation CaptureDefaultLoc,
                         bool ExplicitParams,
-                        bool ExplicitResultType,
                         bool Mutable);
 
+  CXXMethodDecl *CreateLambdaCallOperator(SourceRange IntroducerRange,
+                                          CXXRecordDecl *Class);
+  void buildCompleteLambdaCallOperator(
+      CXXMethodDecl *Method, SourceLocation Loc, Expr *TrailingRequiresClause,
+      TypeSourceInfo *MethodTyInfo, ConstexprSpecKind ConstexprKind,
+      ArrayRef<ParmVarDecl *> Params, bool HasExplicitResultType);
+
   /// Perform initialization analysis of the init-capture and perform
   /// any implicit conversions such as an lvalue-to-rvalue conversion if
   /// not being used to initialize a reference.
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to