r181101 - Implement template support for CapturedStmt
Wei Pan
wei.pan at intel.com
Fri May 3 20:59:07 PDT 2013
Author: wpan
Date: Fri May 3 22:59:06 2013
New Revision: 181101
URL: http://llvm.org/viewvc/llvm-project?rev=181101&view=rev
Log:
Implement template support for CapturedStmt
- Sema tests added and CodeGen tests are pending
Differential Revision: http://llvm-reviews.chandlerc.com/D728
Modified:
cfe/trunk/include/clang/AST/Stmt.h
cfe/trunk/include/clang/Sema/Sema.h
cfe/trunk/lib/AST/Stmt.cpp
cfe/trunk/lib/Sema/SemaStmt.cpp
cfe/trunk/lib/Sema/TreeTransform.h
cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
cfe/trunk/test/SemaCXX/captured-statements.cpp
Modified: cfe/trunk/include/clang/AST/Stmt.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Stmt.h?rev=181101&r1=181100&r2=181101&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Stmt.h (original)
+++ cfe/trunk/include/clang/AST/Stmt.h Fri May 3 22:59:06 2013
@@ -16,6 +16,7 @@
#include "clang/AST/DeclGroup.h"
#include "clang/AST/StmtIterator.h"
+#include "clang/Basic/CapturedStmt.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/SourceLocation.h"
@@ -1982,16 +1983,16 @@ private:
/// \brief The number of variable captured, including 'this'.
unsigned NumCaptures;
- /// \brief The implicit outlined function.
- CapturedDecl *TheCapturedDecl;
+ /// \brief The pointer part is the implicit the outlined function and the
+ /// int part is the captured region kind, 'CR_Default' etc.
+ llvm::PointerIntPair<CapturedDecl *, 1, CapturedRegionKind> CapDeclAndKind;
/// \brief The record for captured variables, a RecordDecl or CXXRecordDecl.
RecordDecl *TheRecordDecl;
/// \brief Construct a captured statement.
- CapturedStmt(Stmt *S, ArrayRef<Capture> Captures,
- ArrayRef<Expr *> CaptureInits,
- CapturedDecl *CD, RecordDecl *RD);
+ CapturedStmt(Stmt *S, CapturedRegionKind Kind, ArrayRef<Capture> Captures,
+ ArrayRef<Expr *> CaptureInits, CapturedDecl *CD, RecordDecl *RD);
/// \brief Construct an empty captured statement.
CapturedStmt(EmptyShell Empty, unsigned NumCaptures);
@@ -2006,6 +2007,7 @@ private:
public:
static CapturedStmt *Create(ASTContext &Context, Stmt *S,
+ CapturedRegionKind Kind,
ArrayRef<Capture> Captures,
ArrayRef<Expr *> CaptureInits,
CapturedDecl *CD, RecordDecl *RD);
@@ -2020,11 +2022,36 @@ public:
}
/// \brief Retrieve the outlined function declaration.
- CapturedDecl *getCapturedDecl() const { return TheCapturedDecl; }
+ CapturedDecl *getCapturedDecl() { return CapDeclAndKind.getPointer(); }
+ const CapturedDecl *getCapturedDecl() const {
+ return const_cast<CapturedStmt *>(this)->getCapturedDecl();
+ }
+
+ /// \brief Set the outlined function declaration.
+ void setCapturedDecl(CapturedDecl *D) {
+ assert(D && "null CapturedDecl");
+ CapDeclAndKind.setPointer(D);
+ }
+
+ /// \brief Retrieve the captured region kind.
+ CapturedRegionKind getCapturedRegionKind() const {
+ return CapDeclAndKind.getInt();
+ }
+
+ /// \brief Set the captured region kind.
+ void setCapturedRegionKind(CapturedRegionKind Kind) {
+ CapDeclAndKind.setInt(Kind);
+ }
/// \brief Retrieve the record declaration for captured variables.
const RecordDecl *getCapturedRecordDecl() const { return TheRecordDecl; }
+ /// \brief Set the record declaration for captured variables.
+ void setCapturedRecordDecl(RecordDecl *D) {
+ assert(D && "null RecordDecl");
+ TheRecordDecl = D;
+ }
+
/// \brief True if this variable has been captured.
bool capturesVariable(const VarDecl *Var) const;
Modified: cfe/trunk/include/clang/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/Sema.h?rev=181101&r1=181100&r2=181101&view=diff
==============================================================================
--- cfe/trunk/include/clang/Sema/Sema.h (original)
+++ cfe/trunk/include/clang/Sema/Sema.h Fri May 3 22:59:06 2013
@@ -2798,7 +2798,7 @@ public:
void ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
CapturedRegionKind Kind, unsigned NumParams);
StmtResult ActOnCapturedRegionEnd(Stmt *S);
- void ActOnCapturedRegionError(bool IsInstantiation = false);
+ void ActOnCapturedRegionError();
RecordDecl *CreateCapturedStmtRecordDecl(CapturedDecl *&CD,
SourceLocation Loc,
unsigned NumParams);
Modified: cfe/trunk/lib/AST/Stmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Stmt.cpp?rev=181101&r1=181100&r2=181101&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Stmt.cpp (original)
+++ cfe/trunk/lib/AST/Stmt.cpp Fri May 3 22:59:06 2013
@@ -1049,12 +1049,13 @@ CapturedStmt::Capture *CapturedStmt::get
+ FirstCaptureOffset);
}
-CapturedStmt::CapturedStmt(Stmt *S, ArrayRef<Capture> Captures,
+CapturedStmt::CapturedStmt(Stmt *S, CapturedRegionKind Kind,
+ ArrayRef<Capture> Captures,
ArrayRef<Expr *> CaptureInits,
CapturedDecl *CD,
RecordDecl *RD)
: Stmt(CapturedStmtClass), NumCaptures(Captures.size()),
- TheCapturedDecl(CD), TheRecordDecl(RD) {
+ CapDeclAndKind(CD, Kind), TheRecordDecl(RD) {
assert( S && "null captured statement");
assert(CD && "null captured declaration for captured statement");
assert(RD && "null record declaration for captured statement");
@@ -1074,11 +1075,12 @@ CapturedStmt::CapturedStmt(Stmt *S, Arra
CapturedStmt::CapturedStmt(EmptyShell Empty, unsigned NumCaptures)
: Stmt(CapturedStmtClass, Empty), NumCaptures(NumCaptures),
- TheCapturedDecl(0), TheRecordDecl(0) {
+ CapDeclAndKind(0, CR_Default), TheRecordDecl(0) {
getStoredStmts()[NumCaptures] = 0;
}
CapturedStmt *CapturedStmt::Create(ASTContext &Context, Stmt *S,
+ CapturedRegionKind Kind,
ArrayRef<Capture> Captures,
ArrayRef<Expr *> CaptureInits,
CapturedDecl *CD,
@@ -1102,7 +1104,7 @@ CapturedStmt *CapturedStmt::Create(ASTCo
}
void *Mem = Context.Allocate(Size);
- return new (Mem) CapturedStmt(S, Captures, CaptureInits, CD, RD);
+ return new (Mem) CapturedStmt(S, Kind, Captures, CaptureInits, CD, RD);
}
CapturedStmt *CapturedStmt::CreateDeserialized(ASTContext &Context,
Modified: cfe/trunk/lib/Sema/SemaStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaStmt.cpp?rev=181101&r1=181100&r2=181101&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaStmt.cpp (original)
+++ cfe/trunk/lib/Sema/SemaStmt.cpp Fri May 3 22:59:06 2013
@@ -2981,7 +2981,8 @@ static void buildCapturedStmtCaptureList
}
void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
- CapturedRegionKind Kind, unsigned NumParams) {
+ CapturedRegionKind Kind,
+ unsigned NumParams) {
CapturedDecl *CD = 0;
RecordDecl *RD = CreateCapturedStmtRecordDecl(CD, Loc, NumParams);
@@ -2996,13 +2997,10 @@ void Sema::ActOnCapturedRegionStart(Sour
PushExpressionEvaluationContext(PotentiallyEvaluated);
}
-void Sema::ActOnCapturedRegionError(bool IsInstantiation) {
+void Sema::ActOnCapturedRegionError() {
DiscardCleanupsInEvaluationContext();
PopExpressionEvaluationContext();
- if (!IsInstantiation)
- PopDeclContext();
-
CapturedRegionScopeInfo *RSI = getCurCapturedRegion();
RecordDecl *Record = RSI->TheRecordDecl;
Record->setInvalidDecl();
@@ -3014,6 +3012,7 @@ void Sema::ActOnCapturedRegionError(bool
ActOnFields(/*Scope=*/0, Record->getLocation(), Record, Fields,
SourceLocation(), SourceLocation(), /*AttributeList=*/0);
+ PopDeclContext();
PopFunctionScopeInfo();
}
@@ -3027,12 +3026,16 @@ StmtResult Sema::ActOnCapturedRegionEnd(
CapturedDecl *CD = RSI->TheCapturedDecl;
RecordDecl *RD = RSI->TheRecordDecl;
- CapturedStmt *Res = CapturedStmt::Create(getASTContext(), S, Captures,
+ CapturedStmt *Res = CapturedStmt::Create(getASTContext(), S,
+ RSI->CapRegionKind, Captures,
CaptureInits, CD, RD);
CD->setBody(Res->getCapturedStmt());
RD->completeDefinition();
+ DiscardCleanupsInEvaluationContext();
+ PopExpressionEvaluationContext();
+
PopDeclContext();
PopFunctionScopeInfo();
Modified: cfe/trunk/lib/Sema/TreeTransform.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/TreeTransform.h?rev=181101&r1=181100&r2=181101&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/TreeTransform.h (original)
+++ cfe/trunk/lib/Sema/TreeTransform.h Fri May 3 22:59:06 2013
@@ -9449,7 +9449,18 @@ TreeTransform<Derived>::RebuildCXXPseudo
template<typename Derived>
StmtResult
TreeTransform<Derived>::TransformCapturedStmt(CapturedStmt *S) {
- llvm_unreachable("not implement yet");
+ SourceLocation Loc = S->getLocStart();
+ unsigned NumParams = S->getCapturedDecl()->getNumParams();
+ getSema().ActOnCapturedRegionStart(Loc, /*CurScope*/0,
+ S->getCapturedRegionKind(), NumParams);
+ StmtResult Body = getDerived().TransformStmt(S->getCapturedStmt());
+
+ if (Body.isInvalid()) {
+ getSema().ActOnCapturedRegionError();
+ return StmtError();
+ }
+
+ return getSema().ActOnCapturedRegionEnd(Body.take());
}
} // end namespace clang
Modified: cfe/trunk/lib/Serialization/ASTReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTReaderStmt.cpp?rev=181101&r1=181100&r2=181101&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTReaderStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTReaderStmt.cpp Fri May 3 22:59:06 2013
@@ -382,8 +382,9 @@ void ASTStmtReader::VisitMSAsmStmt(MSAsm
void ASTStmtReader::VisitCapturedStmt(CapturedStmt *S) {
VisitStmt(S);
- S->TheCapturedDecl = ReadDeclAs<CapturedDecl>(Record, Idx);
- S->TheRecordDecl = ReadDeclAs<RecordDecl>(Record, Idx);
+ S->setCapturedDecl(ReadDeclAs<CapturedDecl>(Record, Idx));
+ S->setCapturedRegionKind(static_cast<CapturedRegionKind>(Record[Idx++]));
+ S->setCapturedRecordDecl(ReadDeclAs<RecordDecl>(Record, Idx));
// Capture inits
for (CapturedStmt::capture_init_iterator I = S->capture_init_begin(),
@@ -393,7 +394,7 @@ void ASTStmtReader::VisitCapturedStmt(Ca
// Body
S->setCapturedStmt(Reader.ReadSubStmt());
- S->TheCapturedDecl->setBody(S->getCapturedStmt());
+ S->getCapturedDecl()->setBody(S->getCapturedStmt());
// Captures
for (CapturedStmt::capture_iterator I = S->capture_begin(),
Modified: cfe/trunk/lib/Serialization/ASTWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Serialization/ASTWriterStmt.cpp?rev=181101&r1=181100&r2=181101&view=diff
==============================================================================
--- cfe/trunk/lib/Serialization/ASTWriterStmt.cpp (original)
+++ cfe/trunk/lib/Serialization/ASTWriterStmt.cpp Fri May 3 22:59:06 2013
@@ -290,7 +290,10 @@ void ASTStmtWriter::VisitCapturedStmt(Ca
// NumCaptures
Record.push_back(std::distance(S->capture_begin(), S->capture_end()));
+ // CapturedDecl and captured region kind
Writer.AddDeclRef(S->getCapturedDecl(), Record);
+ Record.push_back(S->getCapturedRegionKind());
+
Writer.AddDeclRef(S->getCapturedRecordDecl(), Record);
// Capture inits
Modified: cfe/trunk/test/SemaCXX/captured-statements.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/SemaCXX/captured-statements.cpp?rev=181101&r1=181100&r2=181101&view=diff
==============================================================================
--- cfe/trunk/test/SemaCXX/captured-statements.cpp (original)
+++ cfe/trunk/test/SemaCXX/captured-statements.cpp Fri May 3 22:59:06 2013
@@ -50,3 +50,117 @@ class test_this_capture {
{ b(); } // OK
}
};
+
+template <typename T>
+void template_capture_var() {
+ T x; // expected-error{{declaration of reference variable 'x' requires an initializer}}
+ #pragma clang _debug captured
+ {
+ (void)x;
+ }
+}
+
+template <typename T>
+class Val {
+ T v;
+public:
+ void set(const T &v0) {
+ #pragma clang __debug captured
+ {
+ v = v0;
+ }
+ }
+};
+
+void test_capture_var() {
+ template_capture_var<int>(); // OK
+ template_capture_var<int&>(); // expected-note{{in instantiation of function template specialization 'template_capture_var<int &>' requested here}}
+
+ Val<float> Obj;
+ Obj.set(0.0f); // OK
+}
+
+template <typename S, typename T>
+S template_capture_var(S x, T y) {
+ #pragma clang _debug captured
+ {
+ x++;
+ y++; // expected-error{{read-only variable is not assignable}}
+ }
+
+ return x;
+}
+
+// Check if can recover from a template error.
+void test_capture_var_error() {
+ template_capture_var<int, int>(0, 1); // OK
+ template_capture_var<int, const int>(0, 1); // expected-note{{in instantiation of function template specialization 'template_capture_var<int, const int>' requested here}}
+ template_capture_var<int, int>(0, 1); // OK
+}
+
+template <typename T>
+void template_capture_in_lambda() {
+ T x, y;
+ [=, &y]() {
+ #pragma clang __debug captured
+ {
+ y += x;
+ }
+ }();
+}
+
+void test_lambda() {
+ template_capture_in_lambda<int>(); // OK
+}
+
+struct Foo {
+ void foo() { }
+ static void bar() { }
+};
+
+template <typename T>
+void template_capture_func(T &t) {
+ #pragma clang __debug captured
+ {
+ t.foo();
+ }
+
+ #pragma clang __debug captured
+ {
+ T::bar();
+ }
+}
+
+void test_template_capture_func() {
+ Foo Obj;
+ template_capture_func(Obj);
+}
+
+template <typename T>
+T captured_sum(const T &a, const T &b) {
+ T result;
+
+ #pragma clang __debug captured
+ {
+ result = a + b;
+ }
+
+ return result;
+}
+
+template <typename T, typename... Args>
+T captured_sum(const T &a, const Args&... args) {
+ T result;
+
+ #pragma clang __debug captured
+ {
+ result = a + captured_sum(args...);
+ }
+
+ return result;
+}
+
+void test_capture_variadic() {
+ (void)captured_sum(1, 2, 3); // OK
+ (void)captured_sum(1, 2, 3, 4, 5); // OK
+}
More information about the cfe-commits
mailing list