diff options
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/AST/ASTContext.h | 4 | ||||
-rw-r--r-- | include/clang/AST/Decl.h | 74 | ||||
-rw-r--r-- | include/clang/AST/Expr.h | 24 | ||||
-rw-r--r-- | include/clang/Sema/ScopeInfo.h | 7 |
4 files changed, 72 insertions, 37 deletions
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 6d3a9f0619..8a05730154 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -855,9 +855,9 @@ public: void getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, std::string &S) const; - /// getObjCEncodingForBlockDecl - Return the encoded type for this block + /// getObjCEncodingForBlock - Return the encoded type for this block /// declaration. - void getObjCEncodingForBlock(const BlockExpr *Expr, std::string& S) const; + std::string getObjCEncodingForBlock(const BlockExpr *blockExpr) const; /// getObjCEncodingForPropertyDecl - Return the encoded type for /// this method declaration. If non-NULL, Container must be either diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 485883e18b..f81f9d0ca4 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -2493,6 +2493,46 @@ public: /// ^{ statement-body } or ^(int arg1, float arg2){ statement-body } /// class BlockDecl : public Decl, public DeclContext { +public: + /// A class which contains all the information about a particular + /// captured value. + class Capture { + enum { + flag_isByRef = 0x1, + flag_isNested = 0x2 + }; + + /// The variable being captured. + llvm::PointerIntPair<VarDecl*, 2> VariableAndFlags; + + /// The copy expression, expressed in terms of a DeclRef (or + /// BlockDeclRef) to the captured variable. Only required if the + /// variable has a C++ class type. + Expr *CopyExpr; + + public: + Capture(VarDecl *variable, bool byRef, bool nested, Expr *copy) + : VariableAndFlags(variable, + (byRef ? flag_isByRef : 0) | (nested ? flag_isNested : 0)), + CopyExpr(copy) {} + + /// The variable being captured. + VarDecl *getVariable() const { return VariableAndFlags.getPointer(); } + + /// Whether this is a "by ref" capture, i.e. a capture of a __block + /// variable. + bool isByRef() const { return VariableAndFlags.getInt() & flag_isByRef; } + + /// Whether this is a nested capture, i.e. the variable captured + /// is not from outside the immediately enclosing function/block. + bool isNested() const { return VariableAndFlags.getInt() & flag_isNested; } + + bool hasCopyExpr() const { return CopyExpr != 0; } + Expr *getCopyExpr() const { return CopyExpr; } + void setCopyExpr(Expr *e) { CopyExpr = e; } + }; + +private: // FIXME: This can be packed into the bitfields in Decl. bool IsVariadic : 1; bool CapturesCXXThis : 1; @@ -2505,15 +2545,15 @@ class BlockDecl : public Decl, public DeclContext { Stmt *Body; TypeSourceInfo *SignatureAsWritten; - VarDecl **CapturedDecls; - unsigned NumCapturedDecls; + Capture *Captures; + unsigned NumCaptures; protected: BlockDecl(DeclContext *DC, SourceLocation CaretLoc) : Decl(Block, DC, CaretLoc), DeclContext(Block), IsVariadic(false), CapturesCXXThis(false), ParamInfo(0), NumParams(0), Body(0), - SignatureAsWritten(0), CapturedDecls(0), NumCapturedDecls(0) {} + SignatureAsWritten(0), Captures(0), NumCaptures(0) {} public: static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); @@ -2555,25 +2595,25 @@ public: /// hasCaptures - True if this block (or its nested blocks) captures /// anything of local storage from its enclosing scopes. - bool hasCaptures() const { return NumCapturedDecls != 0 || CapturesCXXThis; } + bool hasCaptures() const { return NumCaptures != 0 || CapturesCXXThis; } - unsigned getNumCapturedDecls() const { return NumCapturedDecls; } + /// getNumCaptures - Returns the number of captured variables. + /// Does not include an entry for 'this'. + unsigned getNumCaptures() const { return NumCaptures; } - typedef VarDecl * const *capture_iterator; - typedef VarDecl const * const *capture_const_iterator; - capture_iterator capture_begin() { return CapturedDecls; } - capture_iterator capture_end() { return CapturedDecls + NumCapturedDecls; } - capture_const_iterator capture_begin() const { return CapturedDecls; } - capture_const_iterator capture_end() const { - return CapturedDecls + NumCapturedDecls; - } + typedef const Capture *capture_iterator; + typedef const Capture *capture_const_iterator; + capture_iterator capture_begin() { return Captures; } + capture_iterator capture_end() { return Captures + NumCaptures; } + capture_const_iterator capture_begin() const { return Captures; } + capture_const_iterator capture_end() const { return Captures + NumCaptures; } bool capturesCXXThis() const { return CapturesCXXThis; } - void setCapturedDecls(ASTContext &Context, - VarDecl * const *begin, - VarDecl * const *end, - bool capturesCXXThis); + void setCaptures(ASTContext &Context, + const Capture *begin, + const Capture *end, + bool capturesCXXThis); virtual SourceRange getSourceRange() const; diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index cf1faf1aff..247a4d10ba 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -3565,27 +3565,25 @@ public: virtual child_iterator child_end(); }; -/// BlockDeclRefExpr - A reference to a declared variable, function, -/// enum, etc. +/// BlockDeclRefExpr - A reference to a local variable declared in an +/// enclosing scope. class BlockDeclRefExpr : public Expr { - ValueDecl *D; + VarDecl *D; SourceLocation Loc; bool IsByRef : 1; bool ConstQualAdded : 1; - Stmt *CopyConstructorVal; public: - BlockDeclRefExpr(ValueDecl *d, QualType t, ExprValueKind VK, - SourceLocation l, bool ByRef, bool constAdded = false, - Stmt *copyConstructorVal = 0); + BlockDeclRefExpr(VarDecl *d, QualType t, ExprValueKind VK, + SourceLocation l, bool ByRef, bool constAdded = false); // \brief Build an empty reference to a declared variable in a // block. explicit BlockDeclRefExpr(EmptyShell Empty) : Expr(BlockDeclRefExprClass, Empty) { } - ValueDecl *getDecl() { return D; } - const ValueDecl *getDecl() const { return D; } - void setDecl(ValueDecl *VD) { D = VD; } + VarDecl *getDecl() { return D; } + const VarDecl *getDecl() const { return D; } + void setDecl(VarDecl *VD) { D = VD; } SourceLocation getLocation() const { return Loc; } void setLocation(SourceLocation L) { Loc = L; } @@ -3598,12 +3596,6 @@ public: bool isConstQualAdded() const { return ConstQualAdded; } void setConstQualAdded(bool C) { ConstQualAdded = C; } - const Expr *getCopyConstructorExpr() const - { return cast_or_null<Expr>(CopyConstructorVal); } - Expr *getCopyConstructorExpr() - { return cast_or_null<Expr>(CopyConstructorVal); } - void setCopyConstructorExpr(Expr *E) { CopyConstructorVal = E; } - static bool classof(const Stmt *T) { return T->getStmtClass() == BlockDeclRefExprClass; } diff --git a/include/clang/Sema/ScopeInfo.h b/include/clang/Sema/ScopeInfo.h index 0ba61b34eb..edd1432d8e 100644 --- a/include/clang/Sema/ScopeInfo.h +++ b/include/clang/Sema/ScopeInfo.h @@ -116,8 +116,11 @@ public: /// Its return type may be BuiltinType::Dependent. QualType FunctionType; - /// Captures - The set of variables captured by this block. - llvm::SmallSetVector<VarDecl*, 4> Captures; + /// CaptureMap - A map of captured variables to (index+1) into Captures. + llvm::DenseMap<VarDecl*, unsigned> CaptureMap; + + /// Captures - The captured variables. + llvm::SmallVector<BlockDecl::Capture, 4> Captures; /// CapturesCXXThis - Whether this block captures 'this'. bool CapturesCXXThis; |