From: Douglas Gregor Date: Fri, 17 Apr 2009 19:21:43 +0000 (+0000) Subject: PCH support for blocks X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=84af7c27cdc615ff917a501d61256b4049383c97;p=clang PCH support for blocks git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@69373 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index ccfc9c71e0..c8599ea587 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -2493,9 +2493,13 @@ public: : Expr(BlockExprClass, ty), TheBlock(BD), HasBlockDeclRefExprs(hasBlockDeclRefExprs) {} + /// \brief Build an empty block expression. + explicit BlockExpr(EmptyShell Empty) : Expr(BlockExprClass, Empty) { } + const BlockDecl *getBlockDecl() const { return TheBlock; } BlockDecl *getBlockDecl() { return TheBlock; } - + void setBlockDecl(BlockDecl *BD) { TheBlock = BD; } + // Convenience functions for probing the underlying BlockDecl. SourceLocation getCaretLocation() const; const Stmt *getBody() const; @@ -2511,6 +2515,7 @@ public: /// hasBlockDeclRefExprs - Return true iff the block has BlockDeclRefExpr /// contained inside. bool hasBlockDeclRefExprs() const { return HasBlockDeclRefExprs; } + void setHasBlockDeclRefExprs(bool BDRE) { HasBlockDeclRefExprs = BDRE; } static bool classof(const Stmt *T) { return T->getStmtClass() == BlockExprClass; diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index 04849ddba1..86df2289ac 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -468,7 +468,9 @@ namespace clang { EXPR_GNU_NULL, /// \brief A ShuffleVectorExpr record. EXPR_SHUFFLE_VECTOR, - /// FIXME: BlockExpr + /// \brief BlockExpr + EXPR_BLOCK, + /// \brief A BlockDeclRef record. EXPR_BLOCK_DECL_REF }; diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index e474dc7a70..2e8e7dd287 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -197,6 +197,7 @@ void PCHDeclReader::VisitFileScopeAsmDecl(FileScopeAsmDecl *AD) { void PCHDeclReader::VisitBlockDecl(BlockDecl *BD) { VisitDecl(BD); + BD->setBody(cast_or_null(Reader.ReadStmt())); unsigned NumParams = Record[Idx++]; llvm::SmallVector Params; Params.reserve(NumParams); @@ -294,6 +295,7 @@ namespace { unsigned VisitChooseExpr(ChooseExpr *E); unsigned VisitGNUNullExpr(GNUNullExpr *E); unsigned VisitShuffleVectorExpr(ShuffleVectorExpr *E); + unsigned VisitBlockExpr(BlockExpr *E); unsigned VisitBlockDeclRefExpr(BlockDeclRefExpr *E); }; } @@ -792,6 +794,13 @@ unsigned PCHStmtReader::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { return NumExprs; } +unsigned PCHStmtReader::VisitBlockExpr(BlockExpr *E) { + VisitExpr(E); + E->setBlockDecl(cast_or_null(Reader.GetDecl(Record[Idx++]))); + E->setHasBlockDeclRefExprs(Record[Idx++]); + return 0; +} + unsigned PCHStmtReader::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { VisitExpr(E); E->setDecl(cast(Reader.GetDecl(Record[Idx++]))); @@ -2388,6 +2397,10 @@ Stmt *PCHReader::ReadStmt() { S = new (Context) ShuffleVectorExpr(Empty); break; + case pch::EXPR_BLOCK: + S = new (Context) BlockExpr(Empty); + break; + case pch::EXPR_BLOCK_DECL_REF: // FIXME: untested until we have statement and block support S = new (Context) BlockDeclRefExpr(Empty); diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 14e979f2bc..e71a60051a 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -403,7 +403,7 @@ void PCHDeclWriter::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) { void PCHDeclWriter::VisitBlockDecl(BlockDecl *D) { VisitDecl(D); - // FIXME: emit block body + Writer.AddStmt(D->getBody()); Record.push_back(D->param_size()); for (FunctionDecl::param_iterator P = D->param_begin(), PEnd = D->param_end(); P != PEnd; ++P) @@ -496,6 +496,7 @@ namespace { void VisitChooseExpr(ChooseExpr *E); void VisitGNUNullExpr(GNUNullExpr *E); void VisitShuffleVectorExpr(ShuffleVectorExpr *E); + void VisitBlockExpr(BlockExpr *E); void VisitBlockDeclRefExpr(BlockDeclRefExpr *E); }; } @@ -940,6 +941,13 @@ void PCHStmtWriter::VisitShuffleVectorExpr(ShuffleVectorExpr *E) { Code = pch::EXPR_SHUFFLE_VECTOR; } +void PCHStmtWriter::VisitBlockExpr(BlockExpr *E) { + VisitExpr(E); + Writer.AddDeclRef(E->getBlockDecl(), Record); + Record.push_back(E->hasBlockDeclRefExprs()); + Code = pch::EXPR_BLOCK; +} + void PCHStmtWriter::VisitBlockDeclRefExpr(BlockDeclRefExpr *E) { VisitExpr(E); Writer.AddDeclRef(E->getDecl(), Record); diff --git a/test/PCH/blocks.c b/test/PCH/blocks.c new file mode 100644 index 0000000000..0e5065ccee --- /dev/null +++ b/test/PCH/blocks.c @@ -0,0 +1,12 @@ +// Test this without pch. +// RUN: clang-cc -fblocks -include %S/blocks.h -fsyntax-only -ast-print -o - %s + +// Test with pch. +// RUN: clang-cc -emit-pch -fblocks -o %t %S/blocks.h && +// RUN: clang-cc -fblocks -include-pch %t -fsyntax-only -ast-print -o - %s + +int do_add(int x, int y) { return add(x, y); } + +int do_scaled_add(int a, int b, int s) { + return scaled_add(a, b, s); +} diff --git a/test/PCH/blocks.h b/test/PCH/blocks.h new file mode 100644 index 0000000000..af7bb6fc65 --- /dev/null +++ b/test/PCH/blocks.h @@ -0,0 +1,14 @@ +// Header for PCH test blocks.c + +int call_block(int (^bl)(int x, int y), int a, int b) { + return bl(a, b); +} + +int add(int a, int b) { + return call_block(^(int x, int y) { return x + y; }, a, b); +} + +int scaled_add(int a, int b, int s) { + __block int scale = s; + return call_block(^(int x, int y) { return x*scale + y; }, a, b); +} diff --git a/test/PCH/stmts.c b/test/PCH/stmts.c index c8fbc83a0f..f376a1dd37 100644 --- a/test/PCH/stmts.c +++ b/test/PCH/stmts.c @@ -1,9 +1,9 @@ // Test this without pch. -// RUN: clang-cc -fblocks -include %S/stmts.h -fsyntax-only -ast-print -o - %s +// RUN: clang-cc -include %S/stmts.h -fsyntax-only -ast-print -o - %s // Test with pch. -// RUN: clang-cc -emit-pch -fblocks -o %t %S/stmts.h && -// RUN: clang-cc -fblocks -include-pch %t -fsyntax-only -ast-print -o - %s +// RUN: clang-cc -emit-pch -o %t %S/stmts.h && +// RUN: clang-cc -include-pch %t -fsyntax-only -ast-print -o - %s void g0(void) { f0(5); } int g1(int x) { return f1(x); }