diff options
Diffstat (limited to 'include/clang')
-rw-r--r-- | include/clang/AST/Decl.h | 49 | ||||
-rw-r--r-- | include/clang/AST/DeclBase.h | 6 | ||||
-rw-r--r-- | include/clang/AST/Expr.h | 40 |
3 files changed, 71 insertions, 24 deletions
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index b0acc4c1b7..88cbe85421 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -16,10 +16,12 @@ #include "clang/AST/DeclBase.h" #include "clang/Parse/AccessSpecifier.h" +#include "llvm/ADT/SmallVector.h" namespace clang { class Expr; class Stmt; +class CompoundStmt; class StringLiteral; class IdentifierInfo; @@ -981,6 +983,51 @@ protected: void ReadInRec(llvm::Deserializer& D, ASTContext& C); }; -} // end namespace clang +/// BlockDecl - This represents a block literal declaration, which is like an +/// unnamed FunctionDecl. For example: +/// ^{ statement-body } or ^(int arg1, float arg2){ statement-body } +/// +class BlockDecl : public Decl, public DeclContext { + llvm::SmallVector<ParmVarDecl*, 8> Args; + Stmt *Body; +protected: + BlockDecl(DeclContext *DC, SourceLocation CaretLoc, + ParmVarDecl **args, unsigned numargs, Stmt *body) + : Decl(Block, CaretLoc), DeclContext(Block), + Args(args, args+numargs), Body(body) {} + virtual ~BlockDecl(); + virtual void Destroy(ASTContext& C); + +public: + static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L, + ParmVarDecl **args, unsigned numargs, + CompoundStmt *body); + + SourceLocation getCaretLocation() const { return getLocation(); } + + Stmt *getBody() const { return Body; } + + /// arg_iterator - Iterate over the ParmVarDecl's for this block. + typedef llvm::SmallVector<ParmVarDecl*, 8>::const_iterator param_iterator; + bool param_empty() const { return Args.empty(); } + param_iterator param_begin() const { return Args.begin(); } + param_iterator param_end() const { return Args.end(); } + + // Implement isa/cast/dyncast/etc. + static bool classof(const Decl *D) { return D->getKind() == Block; } + static bool classof(const TranslationUnitDecl *D) { return true; } + +protected: + /// EmitImpl - Serialize this BlockDecl. Called by Decl::Emit. + virtual void EmitImpl(llvm::Serializer& S) const; + + /// CreateImpl - Deserialize a BlockDecl. Called by Decl::Create. + static BlockDecl* CreateImpl(llvm::Deserializer& D, ASTContext& C); + + friend Decl* Decl::Create(llvm::Deserializer& D, ASTContext& C); +}; + +} // end namespace clang + #endif diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index d274fd381d..1ebd25c65f 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -27,6 +27,7 @@ class CXXRecordDecl; class EnumDecl; class ObjCMethodDecl; class ObjCInterfaceDecl; +class BlockDecl; /// Decl - This represents one declaration (or definition), e.g. a variable, /// typedef, function, struct, etc. @@ -81,6 +82,7 @@ public: ObjCPropertyImpl, LinkageSpec, FileScopeAsm, + Block, // [DeclContext] // For each non-leaf class, we now define a mapping to the first/last member // of the class, to allow efficient classof. @@ -243,6 +245,7 @@ protected: /// EnumDecl /// ObjCMethodDecl /// ObjCInterfaceDecl +/// BlockDecl /// class DeclContext { /// DeclKind - This indicates which class this is. @@ -295,6 +298,7 @@ public: bool isFunctionOrMethod() const { switch (DeclKind) { + case Decl::Block: case Decl::Function: case Decl::CXXMethod: case Decl::ObjCMethod: @@ -320,6 +324,7 @@ public: case Decl::Enum: case Decl::ObjCMethod: case Decl::ObjCInterface: + case Decl::Block: return true; default: if (D->getKind() >= Decl::FunctionFirst && @@ -339,6 +344,7 @@ public: static bool classof(const EnumDecl *D) { return true; } static bool classof(const ObjCMethodDecl *D) { return true; } static bool classof(const ObjCInterfaceDecl *D) { return true; } + static bool classof(const BlockDecl *D) { return true; } private: void EmitOutRec(llvm::Serializer& S) const; diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index 2b42424803..7fe172afc4 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -28,6 +28,7 @@ namespace clang { class IdentifierInfo; class ParmVarDecl; class ValueDecl; + class BlockDecl; /// Expr - This represents one expression. Note that Expr's are subclasses of /// Stmt. This allows an expression to be transparently used any place a Stmt @@ -1498,36 +1499,29 @@ public: }; -/// BlockExpr - Represent a block literal with a syntax: +/// BlockExpr - Adaptor class for mixing a BlockDecl with expressions. /// ^{ statement-body } or ^(int arg1, float arg2){ statement-body } class BlockExpr : public Expr { - SourceLocation CaretLocation; - llvm::SmallVector<ParmVarDecl*, 8> Args; - Stmt *Body; +protected: + BlockDecl *TheBlock; public: - BlockExpr(SourceLocation caretloc, QualType ty, ParmVarDecl **args, - unsigned numargs, CompoundStmt *body) : Expr(BlockExprClass, ty), - CaretLocation(caretloc), Args(args, args+numargs), Body(body) {} - - SourceLocation getCaretLocation() const { return CaretLocation; } - - /// getFunctionType - Return the underlying function type for this block. - const FunctionType *getFunctionType() const; + BlockExpr(BlockDecl *BD, QualType ty) : Expr(BlockExprClass, ty), + TheBlock(BD) {} - const CompoundStmt *getBody() const { return cast<CompoundStmt>(Body); } - CompoundStmt *getBody() { return cast<CompoundStmt>(Body); } + BlockDecl *getBlockDecl() { return TheBlock; } + + // Convenience functions for probing the underlying BlockDecl. + SourceLocation getCaretLocation() const; + const Stmt *getBody() const; + Stmt *getBody(); virtual SourceRange getSourceRange() const { - return SourceRange(getCaretLocation(), Body->getLocEnd()); + return SourceRange(getCaretLocation(), getBody()->getLocEnd()); } - /// arg_iterator - Iterate over the ParmVarDecl's for the arguments to this - /// block. - typedef llvm::SmallVector<ParmVarDecl*, 8>::const_iterator arg_iterator; - bool arg_empty() const { return Args.empty(); } - arg_iterator arg_begin() const { return Args.begin(); } - arg_iterator arg_end() const { return Args.end(); } - + /// getFunctionType - Return the underlying function type for this block. + const FunctionType *getFunctionType() const; + static bool classof(const Stmt *T) { return T->getStmtClass() == BlockExprClass; } @@ -1536,7 +1530,7 @@ public: // Iterators virtual child_iterator child_begin(); virtual child_iterator child_end(); - + virtual void EmitImpl(llvm::Serializer& S) const; static BlockExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); }; |