On Feb 14, 2012, at 10:52 AM, Douglas Gregor wrote: > Hi Chad, > > On Feb 14, 2012, at 10:48 AM, Chad Rosier <[email protected]> wrote: > >> Hi Doug, >> The test you added seems to be failing on the clang-x86_64-darwin10-gcc42-RA >> buildbot. > > Should be fixed in r150493.
Thanks, Doug! > > - Doug > >> See: >> http://smooshlab.apple.com:8013/builders/clang-x86_64-darwin10-gcc42-RA/builds/11800 >> >> Complete error message below: >> ******************** TEST 'Clang :: PCH/cxx11-lambdas.cpp' FAILED >> ********************Script: >> -- >> /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-gcc42-RA/clang-build/Release+Asserts/bin/clang >> -cc1 -internal-isystem >> /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-gcc42-RA/clang-build/Release+Asserts/bin/../lib/clang/3.1/include >> -pedantic-errors -std=c++11 -emit-pch >> /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-gcc42-RA/clang.src/test/PCH/cxx11-lambdas.cpp >> -o >> /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-gcc42-RA/clang-build/tools/clang/test/PCH/Output/cxx11-lambdas.cpp.tmp-cxx11 >> /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-gcc42-RA/clang-build/Release+Asserts/bin/clang >> -cc1 -internal-isystem >> /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-gcc42-RA/clang-build/Release+Asserts/bin/../lib/clang/3.1/include >> -ast-print -pedantic-errors -std=c++11 -include-pch >> /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-gcc42-RA/clang-build/tools/clang/test/PCH/Output/cxx11-lambdas.cpp.tmp-cxx11 >> >> /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-gcc42-RA/clang.src/test/PCH/cxx11-lambdas.cpp >> | FileCheck -check-prefix=CHECK-PRINT >> /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-gcc42-RA/clang.src/test/PCH/cxx11-lambdas.cpp >> -- >> Exit Code: 1 >> Command Output (stderr): >> -- >> /Users/buildslave/zorg/buildbot/smooshlab/slave-0.8/build.clang-x86_64-darwin10-gcc42-RA/clang.src/test/PCH/cxx11-lambdas.cpp:35:17: >> error: expected string not found in input >> // CHECK-PRINT: int add_slowly >> ^ >> <stdin>:16:17: note: scanning from here >> return [=, &y] { >> ^ >> <stdin>:31:6: note: possible intended match here >> int i = add_slowly(x, y); >> ^ >> -- >> >> ******************** >> Chad >> >> >> On Feb 14, 2012, at 9:54 AM, Douglas Gregor wrote: >> >>> Author: dgregor >>> Date: Tue Feb 14 11:54:36 2012 >>> New Revision: 150491 >>> >>> URL: http://llvm.org/viewvc/llvm-project?rev=150491&view=rev >>> Log: >>> Implement AST (de-)serialization for lambda expressions. >>> >>> Added: >>> cfe/trunk/test/PCH/cxx11-lambdas.cpp (with props) >>> Modified: >>> cfe/trunk/include/clang/AST/ExprCXX.h >>> cfe/trunk/include/clang/Serialization/ASTBitCodes.h >>> cfe/trunk/lib/AST/ExprCXX.cpp >>> cfe/trunk/lib/Serialization/ASTReaderDecl.cpp >>> cfe/trunk/lib/Serialization/ASTReaderStmt.cpp >>> cfe/trunk/lib/Serialization/ASTWriter.cpp >>> cfe/trunk/lib/Serialization/ASTWriterStmt.cpp >>> >>> Modified: cfe/trunk/include/clang/AST/ExprCXX.h >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprCXX.h?rev=150491&r1=150490&r2=150491&view=diff >>> ============================================================================== >>> --- cfe/trunk/include/clang/AST/ExprCXX.h (original) >>> +++ cfe/trunk/include/clang/AST/ExprCXX.h Tue Feb 14 11:54:36 2012 >>> @@ -1168,6 +1168,14 @@ >>> ArrayRef<unsigned> ArrayIndexStarts, >>> SourceLocation ClosingBrace); >>> >>> + /// \brief Construct an empty lambda expression. >>> + LambdaExpr(EmptyShell Empty, unsigned NumCaptures, bool >>> HasArrayIndexVars) >>> + : Expr(LambdaExprClass, Empty), >>> + NumCaptures(NumCaptures), CaptureDefault(LCD_None), >>> ExplicitParams(false), >>> + ExplicitResultType(false), HasArrayIndexVars(true) { >>> + getStoredStmts()[NumCaptures] = 0; >>> + } >>> + >>> Stmt **getStoredStmts() const { >>> return reinterpret_cast<Stmt **>(const_cast<LambdaExpr *>(this) + 1); >>> } >>> @@ -1198,6 +1206,11 @@ >>> ArrayRef<unsigned> ArrayIndexStarts, >>> SourceLocation ClosingBrace); >>> >>> + /// \brief Construct a new lambda expression that will be deserialized >>> from >>> + /// an external source. >>> + static LambdaExpr *CreateDeserialized(ASTContext &C, unsigned >>> NumCaptures, >>> + unsigned NumArrayIndexVars); >>> + >>> /// \brief Determine the default capture kind for this lambda. >>> LambdaCaptureDefault getCaptureDefault() const { >>> return static_cast<LambdaCaptureDefault>(CaptureDefault); >>> @@ -1271,9 +1284,7 @@ >>> CXXMethodDecl *getCallOperator() const; >>> >>> /// \brief Retrieve the body of the lambda. >>> - CompoundStmt *getBody() const { >>> - return reinterpret_cast<CompoundStmt *>(getStoredStmts()[NumCaptures]); >>> - } >>> + CompoundStmt *getBody() const; >>> >>> /// \brief Determine whether the lambda is mutable, meaning that any >>> /// captures values can be modified. >>> >>> Modified: cfe/trunk/include/clang/Serialization/ASTBitCodes.h >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Serialization/ASTBitCodes.h?rev=150491&r1=150490&r2=150491&view=diff >>> ============================================================================== >>> --- cfe/trunk/include/clang/Serialization/ASTBitCodes.h (original) >>> +++ cfe/trunk/include/clang/Serialization/ASTBitCodes.h Tue Feb 14 11:54:36 >>> 2012 >>> @@ -1180,7 +1180,8 @@ >>> // ARC >>> EXPR_OBJC_BRIDGED_CAST, // ObjCBridgedCastExpr >>> >>> - STMT_MS_DEPENDENT_EXISTS // MSDependentExistsStmt >>> + STMT_MS_DEPENDENT_EXISTS, // MSDependentExistsStmt >>> + EXPR_LAMBDA // LambdaExpr >>> }; >>> >>> /// \brief The kinds of designators that can occur in a >>> >>> Modified: cfe/trunk/lib/AST/ExprCXX.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ExprCXX.cpp?rev=150491&r1=150490&r2=150491&view=diff >>> ============================================================================== >>> --- cfe/trunk/lib/AST/ExprCXX.cpp (original) >>> +++ cfe/trunk/lib/AST/ExprCXX.cpp Tue Feb 14 11:54:36 2012 >>> @@ -832,6 +832,16 @@ >>> ClosingBrace); >>> } >>> >>> +LambdaExpr *LambdaExpr::CreateDeserialized(ASTContext &C, unsigned >>> NumCaptures, >>> + unsigned NumArrayIndexVars) { >>> + unsigned Size = sizeof(LambdaExpr) + sizeof(Stmt *) * (NumCaptures + 1); >>> + if (NumArrayIndexVars) >>> + Size += sizeof(VarDecl) * NumArrayIndexVars >>> + + sizeof(unsigned) * (NumCaptures + 1); >>> + void *Mem = C.Allocate(Size); >>> + return new (Mem) LambdaExpr(EmptyShell(), NumCaptures, NumArrayIndexVars >>> > 0); >>> +} >>> + >>> LambdaExpr::capture_iterator LambdaExpr::capture_begin() const { >>> return getLambdaClass()->getLambdaData().Captures; >>> } >>> @@ -886,6 +896,13 @@ >>> return Result; >>> } >>> >>> +CompoundStmt *LambdaExpr::getBody() const { >>> + if (!getStoredStmts()[NumCaptures]) >>> + getStoredStmts()[NumCaptures] = getCallOperator()->getBody(); >>> + >>> + return reinterpret_cast<CompoundStmt *>(getStoredStmts()[NumCaptures]); >>> +} >>> + >>> bool LambdaExpr::isMutable() const { >>> return (getCallOperator()->getTypeQualifiers() & Qualifiers::Const) == 0; >>> } >>> >>> Modified: cfe/trunk/lib/Serialization/ASTReaderDecl.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderDecl.cpp?rev=150491&r1=150490&r2=150491&view=diff >>> ============================================================================== >>> --- cfe/trunk/lib/Serialization/ASTReaderDecl.cpp (original) >>> +++ cfe/trunk/lib/Serialization/ASTReaderDecl.cpp Tue Feb 14 11:54:36 2012 >>> @@ -1050,6 +1050,7 @@ >>> void ASTDeclReader::ReadCXXDefinitionData( >>> struct CXXRecordDecl::DefinitionData >>> &Data, >>> const RecordData &Record, unsigned &Idx) >>> { >>> + // Note: the caller has deserialized the IsLambda bit already. >>> Data.UserDeclaredConstructor = Record[Idx++]; >>> Data.UserDeclaredCopyConstructor = Record[Idx++]; >>> Data.UserDeclaredMoveConstructor = Record[Idx++]; >>> @@ -1097,6 +1098,25 @@ >>> Reader.ReadUnresolvedSet(F, Data.VisibleConversions, Record, Idx); >>> assert(Data.Definition && "Data.Definition should be already set!"); >>> Data.FirstFriend = ReadDeclAs<FriendDecl>(Record, Idx); >>> + >>> + if (Data.IsLambda) { >>> + typedef LambdaExpr::Capture Capture; >>> + CXXRecordDecl::LambdaDefinitionData &Lambda >>> + = static_cast<CXXRecordDecl::LambdaDefinitionData &>(Data); >>> + Lambda.NumCaptures = Record[Idx++]; >>> + Lambda.NumExplicitCaptures = Record[Idx++]; >>> + Lambda.Captures >>> + = >>> (Capture*)Reader.Context.Allocate(sizeof(Capture)*Lambda.NumCaptures); >>> + Capture *ToCapture = Lambda.Captures; >>> + for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) { >>> + SourceLocation Loc = ReadSourceLocation(Record, Idx); >>> + bool IsImplicit = Record[Idx++]; >>> + LambdaCaptureKind Kind = >>> static_cast<LambdaCaptureKind>(Record[Idx++]); >>> + VarDecl *Var = ReadDeclAs<VarDecl>(Record, Idx); >>> + SourceLocation EllipsisLoc = ReadSourceLocation(Record, Idx); >>> + *ToCapture++ = Capture(Loc, IsImplicit, Kind, Var, EllipsisLoc); >>> + } >>> + } >>> } >>> >>> void ASTDeclReader::VisitCXXRecordDecl(CXXRecordDecl *D) { >>> @@ -1104,7 +1124,13 @@ >>> >>> ASTContext &C = Reader.getContext(); >>> if (Record[Idx++]) { >>> - D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D); >>> + // Determine whether this is a lambda closure type, so that we can >>> + // allocate the appropriate DefinitionData structure. >>> + bool IsLambda = Record[Idx++]; >>> + if (IsLambda) >>> + D->DefinitionData = new (C) CXXRecordDecl::LambdaDefinitionData(D); >>> + else >>> + D->DefinitionData = new (C) struct CXXRecordDecl::DefinitionData(D); >>> >>> // Propagate the DefinitionData pointer to the canonical declaration, so >>> // that all other deserialized declarations will see it. >>> >>> Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=150491&r1=150490&r2=150491&view=diff >>> ============================================================================== >>> --- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original) >>> +++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Tue Feb 14 11:54:36 2012 >>> @@ -1050,7 +1050,31 @@ >>> >>> void ASTStmtReader::VisitLambdaExpr(LambdaExpr *E) { >>> VisitExpr(E); >>> - assert(false && "Cannot deserialize lambda expressions yet"); >>> + unsigned NumCaptures = Record[Idx++]; >>> + assert(NumCaptures == E->NumCaptures);(void)NumCaptures; >>> + unsigned NumArrayIndexVars = Record[Idx++]; >>> + E->IntroducerRange = ReadSourceRange(Record, Idx); >>> + E->CaptureDefault = static_cast<LambdaCaptureDefault>(Record[Idx++]); >>> + E->ExplicitParams = Record[Idx++]; >>> + E->ExplicitResultType = Record[Idx++]; >>> + E->ClosingBrace = ReadSourceLocation(Record, Idx); >>> + >>> + // Read capture initializers. >>> + for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(), >>> + CEnd = E->capture_init_end(); >>> + C != CEnd; ++C) >>> + *C = Reader.ReadSubExpr(); >>> + >>> + // Read array capture index variables. >>> + if (NumArrayIndexVars > 0) { >>> + unsigned *ArrayIndexStarts = E->getArrayIndexStarts(); >>> + for (unsigned I = 0; I != NumCaptures + 1; ++I) >>> + ArrayIndexStarts[I] = Record[Idx++]; >>> + >>> + VarDecl **ArrayIndexVars = E->getArrayIndexVars(); >>> + for (unsigned I = 0; I != NumArrayIndexVars; ++I) >>> + ArrayIndexVars[I] = ReadDeclAs<VarDecl>(Record, Idx); >>> + } >>> } >>> >>> void ASTStmtReader::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) { >>> @@ -2083,6 +2107,14 @@ >>> case EXPR_ATOMIC: >>> S = new (Context) AtomicExpr(Empty); >>> break; >>> + >>> + case EXPR_LAMBDA: { >>> + unsigned NumCaptures = Record[ASTStmtReader::NumExprFields]; >>> + unsigned NumArrayIndexVars = Record[ASTStmtReader::NumExprFields + >>> 1]; >>> + S = LambdaExpr::CreateDeserialized(Context, NumCaptures, >>> + NumArrayIndexVars); >>> + break; >>> + } >>> } >>> >>> // We hit a STMT_STOP, so we're done with this expression. >>> >>> Modified: cfe/trunk/lib/Serialization/ASTWriter.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriter.cpp?rev=150491&r1=150490&r2=150491&view=diff >>> ============================================================================== >>> --- cfe/trunk/lib/Serialization/ASTWriter.cpp (original) >>> +++ cfe/trunk/lib/Serialization/ASTWriter.cpp Tue Feb 14 11:54:36 2012 >>> @@ -4274,6 +4274,7 @@ >>> void ASTWriter::AddCXXDefinitionData(const CXXRecordDecl *D, RecordDataImpl >>> &Record) { >>> assert(D->DefinitionData); >>> struct CXXRecordDecl::DefinitionData &Data = *D->DefinitionData; >>> + Record.push_back(Data.IsLambda); >>> Record.push_back(Data.UserDeclaredConstructor); >>> Record.push_back(Data.UserDeclaredCopyConstructor); >>> Record.push_back(Data.UserDeclaredMoveConstructor); >>> @@ -4325,6 +4326,24 @@ >>> AddUnresolvedSet(Data.VisibleConversions, Record); >>> // Data.Definition is the owning decl, no need to write it. >>> AddDeclRef(Data.FirstFriend, Record); >>> + >>> + // Add lambda-specific data. >>> + if (Data.IsLambda) { >>> + CXXRecordDecl::LambdaDefinitionData &Lambda = D->getLambdaData(); >>> + Record.push_back(Lambda.NumCaptures); >>> + Record.push_back(Lambda.NumExplicitCaptures); >>> + for (unsigned I = 0, N = Lambda.NumCaptures; I != N; ++I) { >>> + LambdaExpr::Capture &Capture = Lambda.Captures[I]; >>> + AddSourceLocation(Capture.getLocation(), Record); >>> + Record.push_back(Capture.isImplicit()); >>> + Record.push_back(Capture.getCaptureKind()); // FIXME: stable! >>> + VarDecl *Var = Capture.capturesVariable()? Capture.getCapturedVar() >>> : 0; >>> + AddDeclRef(Var, Record); >>> + AddSourceLocation(Capture.isPackExpansion()? Capture.getEllipsisLoc() >>> + : SourceLocation(), >>> + Record); >>> + } >>> + } >>> } >>> >>> void ASTWriter::ReaderInitialized(ASTReader *Reader) { >>> >>> Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=150491&r1=150490&r2=150491&view=diff >>> ============================================================================== >>> --- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original) >>> +++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Tue Feb 14 11:54:36 2012 >>> @@ -1024,7 +1024,34 @@ >>> >>> void ASTStmtWriter::VisitLambdaExpr(LambdaExpr *E) { >>> VisitExpr(E); >>> - assert(false && "Cannot serialize lambda expressions yet"); >>> + Record.push_back(E->NumCaptures); >>> + unsigned NumArrayIndexVars = 0; >>> + if (E->HasArrayIndexVars) >>> + NumArrayIndexVars = E->getArrayIndexStarts()[E->NumCaptures]; >>> + Record.push_back(NumArrayIndexVars); >>> + Writer.AddSourceRange(E->IntroducerRange, Record); >>> + Record.push_back(E->CaptureDefault); // FIXME: stable encoding >>> + Record.push_back(E->ExplicitParams); >>> + Record.push_back(E->ExplicitResultType); >>> + Writer.AddSourceLocation(E->ClosingBrace, Record); >>> + >>> + // Add capture initializers. >>> + for (LambdaExpr::capture_init_iterator C = E->capture_init_begin(), >>> + CEnd = E->capture_init_end(); >>> + C != CEnd; ++C) { >>> + Writer.AddStmt(*C); >>> + } >>> + >>> + // Add array index variables, if any. >>> + if (NumArrayIndexVars) { >>> + Record.append(E->getArrayIndexStarts(), >>> + E->getArrayIndexStarts() + E->NumCaptures + 1); >>> + VarDecl **ArrayIndexVars = E->getArrayIndexVars(); >>> + for (unsigned I = 0; I != NumArrayIndexVars; ++I) >>> + Writer.AddDeclRef(ArrayIndexVars[I], Record); >>> + } >>> + >>> + Code = serialization::EXPR_LAMBDA; >>> } >>> >>> void ASTStmtWriter::VisitCXXNamedCastExpr(CXXNamedCastExpr *E) { >>> >>> Added: cfe/trunk/test/PCH/cxx11-lambdas.cpp >>> URL: >>> http://llvm.org/viewvc/llvm-project/cfe/trunk/test/PCH/cxx11-lambdas.cpp?rev=150491&view=auto >>> ============================================================================== >>> --- cfe/trunk/test/PCH/cxx11-lambdas.cpp (added) >>> +++ cfe/trunk/test/PCH/cxx11-lambdas.cpp Tue Feb 14 11:54:36 2012 >>> @@ -0,0 +1,43 @@ >>> +// RUN: %clang_cc1 -pedantic-errors -std=c++11 -emit-pch %s -o %t-cxx11 >>> +// RUN: %clang_cc1 -ast-print -pedantic-errors -std=c++11 -include-pch >>> %t-cxx11 %s | FileCheck -check-prefix=CHECK-PRINT %s >>> + >>> +#ifndef HEADER_INCLUDED >>> + >>> +#define HEADER_INCLUDED >>> +template<typename T> >>> +T add_slowly(const T& x, const T &y) { >>> + return [=, &y] { return x + y; }(); >>> +}; >>> + >>> +inline int add_int_slowly_twice(int x, int y) { >>> + int i = add_slowly(x, y); >>> + auto lambda = [&](int z) { return x + z; }; >>> + return i + lambda(y); >>> +} >>> + >>> +inline int sum_array(int n) { >>> + int array[5] = { 1, 2, 3, 4, 5}; >>> + auto lambda = [=](int N) -> int { >>> + int sum = 0; >>> + for (unsigned I = 0; I < N; ++I) >>> + sum += array[N]; >>> + return sum; >>> + }; >>> + >>> + return lambda(n); >>> +} >>> +#else >>> + >>> +// CHECK-PRINT: float add_slowly >>> +// CHECK-PRINT: return [=, &y] >>> +template float add_slowly(const float&, const float&); >>> + >>> +// CHECK-PRINT: int add_slowly >>> +// CHECK-PRINT: return [=, &y] >>> +int add(int x, int y) { >>> + return add_int_slowly_twice(x, y) + sum_array(4); >>> +} >>> + >>> +// CHECK-PRINT: inline int add_int_slowly_twice >>> +// CHECK-PRINT: lambda = [&] (int z) >>> +#endif >>> >>> Propchange: cfe/trunk/test/PCH/cxx11-lambdas.cpp >>> ------------------------------------------------------------------------------ >>> svn:eol-style = native >>> >>> Propchange: cfe/trunk/test/PCH/cxx11-lambdas.cpp >>> ------------------------------------------------------------------------------ >>> svn:keywords = Id >>> >>> Propchange: cfe/trunk/test/PCH/cxx11-lambdas.cpp >>> ------------------------------------------------------------------------------ >>> svn:mime-type = text/plain >>> >>> >>> _______________________________________________ >>> cfe-commits mailing list >>> [email protected] >>> http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits >> >
_______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
