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

Alexey Bataev a.bataev at hotmail.com
Sun Jul 20 23:17:40 PDT 2014


================
Comment at: lib/AST/Decl.cpp:3265
@@ +3264,3 @@
+      InitializerOrBitWidth.getPointer()) {
+    if (getDeclContext() && getDeclContext()->isRecord()) {
+      if (auto *RD = dyn_cast<CXXRecordDecl>(getParent())) {
----------------
Richard Smith wrote:
> You don't need the `isRecord` check here, and you shouldn't need the `getDeclContext` check either. If some buggy code is querying this when there is no `DeclContext`, it'd be better to crash or assert because you cannot give a correct answer.
I need it, because there are classes ObjCIvarDecl and ObjCAtDefsFieldDecl, derived from FieldDecl, and the parents for instances of these classes are not RecordDecl, but some ObjC specific constructs.

================
Comment at: lib/AST/Decl.cpp:3309
@@ -3295,3 +3308,3 @@
   InitializerOrBitWidth.setPointer(Width);
 }
 
----------------
Richard Smith wrote:
> Please `assert(isBitField())` or similar here to ensure that we don't set a bit width on a lambda capture.
Ok

================
Comment at: lib/AST/Decl.cpp:3328-3329
@@ +3327,4 @@
+void FieldDecl::setCapturedVLABoundExpr(Expr *CapturedExpr) {
+  assert(isa<CXXRecordDecl>(getParent()) &&
+         cast<CXXRecordDecl>(getParent())->isLambda() &&
+         "capturing expression in non-lambda.");
----------------
Richard Smith wrote:
> Given the number of times you do this `isa<CXXRecordDecl> && isLambda` check, I'd prefer for you to add an `isLambda` member to `RecordDecl` and have it do the `dyn_cast` to `CXXRecordDecl`.
Ok

================
Comment at: lib/Sema/SemaExpr.cpp:12220-12235
@@ +12219,18 @@
+            if (auto LSI = dyn_cast<LambdaScopeInfo>(CSI)) {
+              auto Loc = Size->getExprLoc();
+              auto QType = Size->getType();
+              auto QArrayType = QualType(Vat, 0);
+              auto TInfo = Context.getTrivialTypeSourceInfo(QType, Loc);
+              auto QArrayTInfo =
+                  Context.getTrivialTypeSourceInfo(QArrayType, Loc);
+              auto VD = VarDecl::Create(Context, getFunctionLevelDeclContext(),
+                                        SourceLocation(), SourceLocation(),
+                                        &Context.Idents.get(".captured_expr."),
+                                        QArrayType, QArrayTInfo, SC_Auto);
+              auto DRE =
+                  new (Context) DeclRefExpr(VD, /*refersToEnclosingLocal*/ true,
+                                            QArrayType, VK_LValue, Loc);
+              auto BinExpr = new (Context) BinaryOperator(
+                  DRE, Size, BO_Comma, QType, Size->getValueKind(), OK_Ordinary,
+                  Loc, /*fpContractable*/ false);
+              auto Lambda = LSI->Lambda;
----------------
Richard Smith wrote:
> This seems like a hack: could you instead make the `FieldDecl` directly store the `VariableArrayType *`, rather than creating a proxy expression and variable to carry it?
I'll try, but I'm not sure that it will work. I'm not sure can we store VLA as the element of the structure in LLVM IR? I'll try to improve it.

http://reviews.llvm.org/D4368






More information about the cfe-commits mailing list