diff options
author | David Chisnall <csdavec@swan.ac.uk> | 2009-11-17 19:33:30 +0000 |
---|---|---|
committer | David Chisnall <csdavec@swan.ac.uk> | 2009-11-17 19:33:30 +0000 |
commit | 950a9518b11b0966ba434d23fa6b98b4d810ff51 (patch) | |
tree | 29e52e9d6c6da3b6ccb4cc6d684c0dd2239e7221 /clang/lib/AST/ASTContext.cpp | |
parent | cb1b7bf79dd2ab190606f809ac373c0b6d2e4d36 (diff) | |
download | bcm5719-llvm-950a9518b11b0966ba434d23fa6b98b4d810ff51.tar.gz bcm5719-llvm-950a9518b11b0966ba434d23fa6b98b4d810ff51.zip |
Added block type introspection support.
As per Fariborz's suggestion, committed now but can be reverted later if the used flag is problematic for Apple.
llvm-svn: 89134
Diffstat (limited to 'clang/lib/AST/ASTContext.cpp')
-rw-r--r-- | clang/lib/AST/ASTContext.cpp | 48 |
1 files changed, 48 insertions, 0 deletions
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp index 1b3e09291dd..c3dc8bc4da6 100644 --- a/clang/lib/AST/ASTContext.cpp +++ b/clang/lib/AST/ASTContext.cpp @@ -3071,6 +3071,54 @@ int ASTContext::getObjCEncodingTypeSize(QualType type) { return sz / getTypeSize(CharTy); } +/// getObjCEncodingForBlockDecl - Return the encoded type for this method +/// declaration. +void ASTContext::getObjCEncodingForBlock(const BlockExpr *Expr, + std::string& S) { + const BlockDecl *Decl = Expr->getBlockDecl(); + QualType BlockTy = + Expr->getType()->getAs<BlockPointerType>()->getPointeeType(); + // Encode result type. + getObjCEncodingForType(cast<FunctionType>(BlockTy)->getResultType(), S); + // Compute size of all parameters. + // Start with computing size of a pointer in number of bytes. + // FIXME: There might(should) be a better way of doing this computation! + SourceLocation Loc; + int PtrSize = getTypeSize(VoidPtrTy) / getTypeSize(CharTy); + int ParmOffset = PtrSize; + for (ObjCMethodDecl::param_iterator PI = Decl->param_begin(), + E = Decl->param_end(); PI != E; ++PI) { + QualType PType = (*PI)->getType(); + int sz = getObjCEncodingTypeSize(PType); + assert (sz > 0 && "BlockExpr - Incomplete param type"); + ParmOffset += sz; + } + // Size of the argument frame + S += llvm::utostr(ParmOffset); + // Block pointer and offset. + S += "@?0"; + ParmOffset = PtrSize; + + // Argument types. + ParmOffset = PtrSize; + for (BlockDecl::param_const_iterator PI = Decl->param_begin(), E = + Decl->param_end(); PI != E; ++PI) { + ParmVarDecl *PVDecl = *PI; + QualType PType = PVDecl->getOriginalType(); + if (const ArrayType *AT = + dyn_cast<ArrayType>(PType->getCanonicalTypeInternal())) { + // Use array's original type only if it has known number of + // elements. + if (!isa<ConstantArrayType>(AT)) + PType = PVDecl->getType(); + } else if (PType->isFunctionType()) + PType = PVDecl->getType(); + getObjCEncodingForType(PType, S); + S += llvm::utostr(ParmOffset); + ParmOffset += getObjCEncodingTypeSize(PType); + } +} + /// getObjCEncodingForMethodDecl - Return the encoded type for this method /// declaration. void ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, |