aboutsummaryrefslogtreecommitdiff
path: root/include/clang
diff options
context:
space:
mode:
Diffstat (limited to 'include/clang')
-rw-r--r--include/clang/AST/ASTContext.h4
-rw-r--r--include/clang/AST/Decl.h74
-rw-r--r--include/clang/AST/Expr.h24
-rw-r--r--include/clang/Sema/ScopeInfo.h7
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;