Final phase of converting BlockDecls over to DeclContext. This is unfortunately a largish/complex diff, however it was necessry to pass all the current block tests.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@57337 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index bb8c14c..575daa5 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -990,24 +990,30 @@
class BlockDecl : public Decl, public DeclContext {
llvm::SmallVector<ParmVarDecl*, 8> Args;
Stmt *Body;
+
+ // Since BlockDecl's aren't named/scoped, we need to store the context.
+ DeclContext *ParentContext;
protected:
- BlockDecl(DeclContext *DC, SourceLocation CaretLoc,
- ParmVarDecl **args, unsigned numargs)
- : Decl(Block, CaretLoc), DeclContext(Block),
- Args(args, args+numargs), Body(0) {}
+ BlockDecl(DeclContext *DC, SourceLocation CaretLoc)
+ : Decl(Block, CaretLoc), DeclContext(Block), Body(0), ParentContext(DC) {}
virtual ~BlockDecl();
virtual void Destroy(ASTContext& C);
public:
- static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L,
- ParmVarDecl **args, unsigned numargs);
+ static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L);
SourceLocation getCaretLocation() const { return getLocation(); }
Stmt *getBody() const { return Body; }
void setBody(Stmt *B) { Body = B; }
+ void setArgs(ParmVarDecl **args, unsigned numargs) {
+ Args.clear();
+ Args.insert(Args.begin(), args, args+numargs);
+ }
+ DeclContext *getParentContext() { return ParentContext; }
+
/// 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(); }
@@ -1016,7 +1022,7 @@
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return D->getKind() == Block; }
- static bool classof(const TranslationUnitDecl *D) { return true; }
+ static bool classof(const BlockDecl *D) { return true; }
protected:
/// EmitImpl - Serialize this BlockDecl. Called by Decl::Emit.
diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h
index 1ebd25c..b165991 100644
--- a/include/clang/AST/DeclBase.h
+++ b/include/clang/AST/DeclBase.h
@@ -267,6 +267,8 @@
static To *CastTo(const From *D) {
Decl::Kind DK = KindTrait<From>::getKind(D);
switch(DK) {
+ case Decl::Block:
+ return static_cast<BlockDecl*>(const_cast<From*>(D));
case Decl::TranslationUnit:
return static_cast<TranslationUnitDecl*>(const_cast<From*>(D));
case Decl::Namespace:
diff --git a/include/clang/Parse/Action.h b/include/clang/Parse/Action.h
index ee7b7a9..a327292 100644
--- a/include/clang/Parse/Action.h
+++ b/include/clang/Parse/Action.h
@@ -538,8 +538,11 @@
/// ActOnBlockStart - This callback is invoked when a block literal is
/// started. The result pointer is passed into the block finalizers.
- virtual void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope,
- Declarator &ParamInfo) {}
+ virtual void ActOnBlockStart(SourceLocation CaretLoc, Scope *CurScope) {}
+
+ /// ActOnBlockArguments - This callback allows processing of block arguments.
+ /// If there are no arguments, this is still invoked.
+ virtual void ActOnBlockArguments(Declarator &ParamInfo) {}
/// ActOnBlockError - If there is an error parsing a block, this callback
/// is invoked to pop the information about the block from the action impl.