[PATCH] [C++11] Support for capturing of variable length arrays in lambda expression.

Alexey Bataev a.bataev at hotmail.com
Tue Jul 22 23:57:11 PDT 2014


Testcase:

serialization, - done(see head of the new test in CodeGenCXX)
generic lambdas - there is one, I'll add more,
capturing multiple array bounds from a single variable - will be added,
referencing the same VLA type multiple times in a single lambda-expression - will be added,
applying sizeof to a captured VLA type within a lambda expression - will be added.

================
Comment at: include/clang/AST/Decl.h:2260-2266
@@ +2259,9 @@
+  /// \brief Get the captured variable length array type.
+  const Type *getCapturedVLAType() const {
+    return hasCapturedVLAType()
+               ? static_cast<const Type *>(InitializerOrBitWidth.getPointer())
+               : nullptr;
+  }
+  /// \brief Set the captured variable length array type for this field.
+  void setCapturedVLAType(const Type *VLAType);
+
----------------
Richard Smith wrote:
> Can you use `VariableArrayType*` instead of just `Type*` here?
Will do

================
Comment at: include/clang/Sema/ScopeInfo.h:405-409
@@ -404,1 +404,7 @@
 
+    Capture(SourceLocation Loc, SourceLocation EllipsisLoc,
+            QualType CaptureType, const Type *Tpy)
+        : VarAndNested(nullptr, /*isNested*/ false),
+          InitExprAndCaptureKind(const_cast<Type *>(Tpy), Cap_ByCopy), Loc(Loc),
+          EllipsisLoc(EllipsisLoc), CaptureType(CaptureType) {}
+
----------------
Richard Smith wrote:
> This seems unnecessary; the `Capture` does not need to know the type.
Ok, I'll remove it

================
Comment at: include/clang/Sema/ScopeInfo.h:433
@@ -426,2 +432,3 @@
     }
-    bool isNested() { return VarAndNested.getInt(); }
+    bool isTypeCapture() const {
+      return InitExprAndCaptureKind.getInt() == Cap_ByCopy &&
----------------
Richard Smith wrote:
> Please call this `isVLACapture()` so that a reader can tell what it's for.
Ok

================
Comment at: include/clang/Sema/ScopeInfo.h:496
@@ -480,1 +495,3 @@
 
+  void addVLATypeCapture(SourceLocation Loc, SourceLocation EllipsisLoc,
+                         QualType CaptureType, const Type *Tpy) {
----------------
Richard Smith wrote:
> There cannot be an ellipsis, because a VLA capture is always implicit.
Ok

================
Comment at: lib/CodeGen/CGExprCXX.cpp:1815
@@ +1814,3 @@
+             "Captured type is not a variable length array type.");
+      auto QArrayType = cast<VariableArrayType>(
+          CurField->getCapturedVLAType()->getAsArrayTypeUnsafe());
----------------
Richard Smith wrote:
> This `QBlah` naming convention is not one we use. We'd usually call this `VAT` or similar.
Ok

================
Comment at: lib/Sema/SemaExpr.cpp:12216-12217
@@ -12218,3 +12215,4 @@
           // Otherwise, evaluate and record it.
-          if (Expr *Size = Vat->getSizeExpr()) {
-            MarkDeclarationsReferencedInExpr(Size);
+          if (auto Size = VAT->getSizeExpr()) {
+            if (auto LSI = dyn_cast<LambdaScopeInfo>(CSI)) {
+              auto Loc = Size->getExprLoc();
----------------
Richard Smith wrote:
> You shouldn't do this if `LSI` has already captured this VLA type.
Ok, I'll fix it

================
Comment at: lib/Sema/SemaExpr.cpp:12219
@@ +12218,3 @@
+              auto Loc = Size->getExprLoc();
+              auto QType = Size->getType();
+              auto Lambda = LSI->Lambda;
----------------
Richard Smith wrote:
> This seems like the wrong type; VLA bounds are always implicitly converted to `size_t`, but we don't model that conversion in the size expression. I'd suggest just always using `Context.getSizeType()` here. Otherwise you'll get asserts in CodeGen because its widened type doesn't match the captured field type.
Ok, I'll fix it

================
Comment at: lib/Sema/SemaExpr.cpp:12233
@@ +12232,3 @@
+
+              LSI->addVLATypeCapture(Loc, Loc, QType, VAT);
+            } else {
----------------
Richard Smith wrote:
> This doesn't seem like a good location for the capture; `ExprLoc` would be better.
Ok

================
Comment at: test/CodeGenCXX/instantiate-typeof-vla.cpp:1
@@ +1,2 @@
+// RUN: %clang_cc1 %s -std=c++11 -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 %s -std=c++11 -emit-pch -o %t
----------------
Richard Smith wrote:
> Please name this test as something to do with VLAs and lambdas. `__typeof` is incidental here.
Ok

http://reviews.llvm.org/D4368






More information about the cfe-commits mailing list