diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index 1991d934ea..1296c2fda9 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -1183,12 +1183,18 @@ protected: /// ^{ statement-body } or ^(int arg1, float arg2){ statement-body } /// class BlockDecl : public Decl, public DeclContext { - llvm::SmallVector Args; + /// ParamInfo - new[]'d array of pointers to ParmVarDecls for the formal + /// parameters of this function. This is null if a prototype or if there are + /// no formals. + ParmVarDecl **ParamInfo; + unsigned NumParams; + Stmt *Body; protected: BlockDecl(DeclContext *DC, SourceLocation CaretLoc) - : Decl(Block, DC, CaretLoc), DeclContext(Block), Body(0) {} + : Decl(Block, DC, CaretLoc), DeclContext(Block), + ParamInfo(0), NumParams(0), Body(0) {} virtual ~BlockDecl(); virtual void Destroy(ASTContext& C); @@ -1201,16 +1207,28 @@ public: CompoundStmt *getBody() const { return (CompoundStmt*) Body; } void setBody(CompoundStmt *B) { Body = (Stmt*) B; } - void setArgs(ParmVarDecl **args, unsigned numargs) { - Args.clear(); - Args.insert(Args.begin(), args, args+numargs); - } + // Iterator access to formal parameters. + unsigned param_size() const { return getNumParams(); } + typedef ParmVarDecl **param_iterator; + typedef ParmVarDecl * const *param_const_iterator; - /// arg_iterator - Iterate over the ParmVarDecl's for this block. - typedef llvm::SmallVector::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(); } + bool param_empty() const { return NumParams == 0; } + param_iterator param_begin() { return ParamInfo; } + param_iterator param_end() { return ParamInfo+param_size(); } + + param_const_iterator param_begin() const { return ParamInfo; } + param_const_iterator param_end() const { return ParamInfo+param_size(); } + + unsigned getNumParams() const; + const ParmVarDecl *getParamDecl(unsigned i) const { + assert(i < getNumParams() && "Illegal param #"); + return ParamInfo[i]; + } + ParmVarDecl *getParamDecl(unsigned i) { + assert(i < getNumParams() && "Illegal param #"); + return ParamInfo[i]; + } + void setParams(ASTContext& C, ParmVarDecl **NewParamInfo, unsigned NumParams); // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return D->getKind() == Block; } diff --git a/lib/AST/Decl.cpp b/lib/AST/Decl.cpp index 5786c56210..bd16331c1b 100644 --- a/lib/AST/Decl.cpp +++ b/lib/AST/Decl.cpp @@ -514,3 +514,20 @@ void BlockDecl::Destroy(ASTContext& C) { Decl::Destroy(C); } + +void BlockDecl::setParams(ASTContext& C, ParmVarDecl **NewParamInfo, + unsigned NParms) { + assert(ParamInfo == 0 && "Already has param info!"); + + // Zero params -> null pointer. + if (NParms) { + NumParams = NParms; + void *Mem = C.Allocate(sizeof(ParmVarDecl*)*NumParams); + ParamInfo = new (Mem) ParmVarDecl*[NumParams]; + memcpy(ParamInfo, NewParamInfo, sizeof(ParmVarDecl*)*NumParams); + } +} + +unsigned BlockDecl::getNumParams() const { + return NumParams; +} diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp index 53e52ad478..f61d75b0f8 100644 --- a/lib/CodeGen/CGBlocks.cpp +++ b/lib/CodeGen/CGBlocks.cpp @@ -624,7 +624,7 @@ CodeGenFunction::GenerateBlockFunction(const BlockExpr *BExpr, Args.push_back(std::make_pair(SelfDecl, SelfDecl->getType())); BlockStructDecl = SelfDecl; - for (BlockDecl::param_iterator i = BD->param_begin(), + for (BlockDecl::param_const_iterator i = BD->param_begin(), e = BD->param_end(); i != e; ++i) Args.push_back(std::make_pair(*i, (*i)->getType())); diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 8324d8d472..4a314525bf 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -4595,7 +4595,8 @@ void Sema::ActOnBlockArguments(Declarator &ParamInfo, Scope *CurScope) { if (!RetTy->isDependentType()) CurBlock->ReturnType = RetTy; } - CurBlock->TheDecl->setArgs(&CurBlock->Params[0], CurBlock->Params.size()); + CurBlock->TheDecl->setParams(Context, &CurBlock->Params[0], + CurBlock->Params.size()); for (BlockDecl::param_iterator AI = CurBlock->TheDecl->param_begin(), E = CurBlock->TheDecl->param_end(); AI != E; ++AI)