diff options
author | Tareq A. Siraj <tareq.a.sriaj@intel.com> | 2013-04-16 18:53:08 +0000 |
---|---|---|
committer | Tareq A. Siraj <tareq.a.sriaj@intel.com> | 2013-04-16 18:53:08 +0000 |
commit | 051303ce09291dfbed537fa33b0d8a4d92c82b75 (patch) | |
tree | 009bdace0e61c4a9e4c25c9337551de59b007e3c /include | |
parent | 85192c7fe187d5486e12dbc6960af28f16a558a0 (diff) | |
download | clang-051303ce09291dfbed537fa33b0d8a4d92c82b75.tar.gz |
Implement CapturedStmt AST
CapturedStmt can be used to implement generic function outlining as described in
http://lists.cs.uiuc.edu/pipermail/cfe-dev/2013-January/027540.html.
CapturedStmt is not exposed to the C api.
Serialization and template support are pending.
Author: Wei Pan <wei.pan@intel.com>
Differential Revision: http://llvm-reviews.chandlerc.com/D370
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@179615 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include')
-rw-r--r-- | include/clang/AST/RecursiveASTVisitor.h | 1 | ||||
-rw-r--r-- | include/clang/AST/Stmt.h | 166 | ||||
-rw-r--r-- | include/clang/Basic/StmtNodes.td | 1 | ||||
-rw-r--r-- | include/clang/Serialization/ASTBitCodes.h | 2 |
4 files changed, 170 insertions, 0 deletions
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h index 33534ecc7c..9b4e481bfd 100644 --- a/include/clang/AST/RecursiveASTVisitor.h +++ b/include/clang/AST/RecursiveASTVisitor.h @@ -2218,6 +2218,7 @@ DEF_TRAVERSE_STMT(UnresolvedMemberExpr, { DEF_TRAVERSE_STMT(SEHTryStmt, {}) DEF_TRAVERSE_STMT(SEHExceptStmt, {}) DEF_TRAVERSE_STMT(SEHFinallyStmt,{}) +DEF_TRAVERSE_STMT(CapturedStmt, {}) DEF_TRAVERSE_STMT(CXXOperatorCallExpr, { }) DEF_TRAVERSE_STMT(OpaqueValueExpr, { }) diff --git a/include/clang/AST/Stmt.h b/include/clang/AST/Stmt.h index cf8fc249c5..c2cfaa486c 100644 --- a/include/clang/AST/Stmt.h +++ b/include/clang/AST/Stmt.h @@ -33,12 +33,14 @@ namespace clang { class Attr; class Decl; class Expr; + class FunctionDecl; class IdentifierInfo; class LabelDecl; class ParmVarDecl; class PrinterHelper; struct PrintingPolicy; class QualType; + class RecordDecl; class SourceManager; class StringLiteral; class SwitchStmt; @@ -1882,6 +1884,170 @@ public: } }; +/// \brief This captures a statement into a function. For example, the following +/// pragma annotated compound statement can be represented as a CapturedStmt, +/// and this compound statement is the body of an anonymous outlined function. +/// @code +/// #pragma omp parallel +/// { +/// compute(); +/// } +/// @endcode +class CapturedStmt : public Stmt { +public: + /// \brief The different capture forms: by 'this' or by reference, etc. + enum VariableCaptureKind { + VCK_This, + VCK_ByRef + }; + + /// \brief Describes the capture of either a variable or 'this'. + class Capture { + VarDecl *Var; + SourceLocation Loc; + + public: + /// \brief Create a new capture. + /// + /// \param Loc The source location associated with this capture. + /// + /// \param Kind The kind of capture (this, ByRef, ...). + /// + /// \param Var The variable being captured, or null if capturing this. + /// + Capture(SourceLocation Loc, VariableCaptureKind Kind, VarDecl *Var = 0) + : Var(Var), Loc(Loc) { + switch (Kind) { + case VCK_This: + assert(Var == 0 && "'this' capture cannot have a variable!"); + break; + case VCK_ByRef: + assert(Var && "capturing by reference must have a variable!"); + break; + } + } + + /// \brief Determine the kind of capture. + VariableCaptureKind getCaptureKind() const { + if (capturesThis()) + return VCK_This; + + return VCK_ByRef; + } + + /// \brief Retrieve the source location at which the variable or 'this' was + /// first used. + SourceLocation getLocation() const { return Loc; } + + /// \brief Determine whether this capture handles the C++ 'this' pointer. + bool capturesThis() const { return Var == 0; } + + /// \brief Determine whether this capture handles a variable. + bool capturesVariable() const { return Var != 0; } + + /// \brief Retrieve the declaration of the variable being captured. + /// + /// This operation is only valid if this capture does not capture 'this'. + VarDecl *getCapturedVar() const { + assert(!capturesThis() && "No variable available for 'this' capture"); + return Var; + } + }; + +private: + /// \brief The number of variable captured, including 'this'. + unsigned NumCaptures; + + /// \brief The implicit outlined function. + FunctionDecl *TheFuncDecl; + + /// \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, + FunctionDecl *FD, RecordDecl *RD); + + /// \brief Construct an empty captured statement. + CapturedStmt(EmptyShell Empty, unsigned NumCaptures); + + Stmt **getStoredStmts() const { + return reinterpret_cast<Stmt **>(const_cast<CapturedStmt *>(this) + 1); + } + + Capture *getStoredCaptures() const; + +public: + static CapturedStmt *Create(ASTContext &Context, Stmt *S, + ArrayRef<Capture> Captures, + ArrayRef<Expr *> CaptureInits, + FunctionDecl *FD, RecordDecl *RD); + + static CapturedStmt *CreateDeserialized(ASTContext &Context, + unsigned NumCaptures); + + /// \brief Retrieve the statement being captured. + Stmt *getCapturedStmt() { return getStoredStmts()[NumCaptures]; } + const Stmt *getCapturedStmt() const { + return const_cast<CapturedStmt *>(this)->getCapturedStmt(); + } + + /// \brief Retrieve the outlined function declaration. + const FunctionDecl *getCapturedFunctionDecl() const { return TheFuncDecl; } + + /// \brief Retrieve the record declaration for captured variables. + const RecordDecl *getCapturedRecordDecl() const { return TheRecordDecl; } + + /// \brief True if this variable has been captured. + bool capturesVariable(const VarDecl *Var) const; + + /// \brief An iterator that walks over the captures. + typedef const Capture *capture_iterator; + + /// \brief Retrieve an iterator pointing to the first capture. + capture_iterator capture_begin() const { return getStoredCaptures(); } + + /// \brief Retrieve an iterator pointing past the end of the sequence of + /// captures. + capture_iterator capture_end() const { + return getStoredCaptures() + NumCaptures; + } + + /// \brief Retrieve the number of captures, including 'this'. + unsigned capture_size() const { return NumCaptures; } + + /// \brief Iterator that walks over the capture initialization arguments. + typedef Expr **capture_init_iterator; + + /// \brief Retrieve the first initialization argument. + capture_init_iterator capture_init_begin() const { + return reinterpret_cast<Expr **>(getStoredStmts()); + } + + /// \brief Retrieve the iterator pointing one past the last initialization + /// argument. + capture_init_iterator capture_init_end() const { + return capture_init_begin() + NumCaptures; + } + + SourceLocation getLocStart() const LLVM_READONLY { + return getCapturedStmt()->getLocStart(); + } + SourceLocation getLocEnd() const LLVM_READONLY { + return getCapturedStmt()->getLocEnd(); + } + SourceRange getSourceRange() const LLVM_READONLY { + return getCapturedStmt()->getSourceRange(); + } + + static bool classof(const Stmt *T) { + return T->getStmtClass() == CapturedStmtClass; + } + + child_range children(); +}; + } // end namespace clang #endif diff --git a/include/clang/Basic/StmtNodes.td b/include/clang/Basic/StmtNodes.td index 979555e1a6..ad25e57c89 100644 --- a/include/clang/Basic/StmtNodes.td +++ b/include/clang/Basic/StmtNodes.td @@ -27,6 +27,7 @@ def DeclStmt : Stmt; def SwitchCase : Stmt<1>; def CaseStmt : DStmt<SwitchCase>; def DefaultStmt : DStmt<SwitchCase>; +def CapturedStmt : Stmt; // Asm statements def AsmStmt : Stmt<1>; diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index e3f9e0643a..04d6a85860 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -1103,6 +1103,8 @@ namespace clang { STMT_RETURN, /// \brief A DeclStmt record. STMT_DECL, + /// \brief A CapturedStmt record. + STMT_CAPTURED, /// \brief A GCC-style AsmStmt record. STMT_GCCASM, /// \brief A MS-style AsmStmt record. |