diff options
author | Bob Wilson <bob.wilson@apple.com> | 2011-11-30 01:57:58 +0000 |
---|---|---|
committer | Bob Wilson <bob.wilson@apple.com> | 2011-11-30 01:57:58 +0000 |
commit | dc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7 (patch) | |
tree | e07864cea78427256faac4556a5f09178139d96d /lib/AST/ASTContext.cpp | |
parent | dff466c0791465f929a1d8cd551d4c84b360ba32 (diff) |
Add bigger method type encodings to protocol objects. <rdar://problem/10492418>
The new metadata are method @encode strings with additional data.
1. Each Objective-C object is marked with its class name and protocol names.
The same is done for property @encode already.
2. Each block object is marked with its function prototype's @encoding. For
example, a method parameter that is a block object that itself returns void
and takes an int would look like:
@?<v@?i>
These new method @encode strings are stored in a single array pointed to by structs protocol_t and objc_protocol_ext.
Patch provided by Greg Parker!
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@145469 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/AST/ASTContext.cpp')
-rw-r--r-- | lib/AST/ASTContext.cpp | 76 |
1 files changed, 63 insertions, 13 deletions
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 2e898f188e..22b5ed803d 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -4080,15 +4080,32 @@ bool ASTContext::getObjCEncodingForFunctionDecl(const FunctionDecl *Decl, return false; } +/// getObjCEncodingForMethodParameter - Return the encoded type for a single +/// method parameter or return type. If Extended, include class names and +/// block object types. +void ASTContext::getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT, + QualType T, std::string& S, + bool Extended) const { + // Encode type qualifer, 'in', 'inout', etc. for the parameter. + getObjCEncodingForTypeQualifier(QT, S); + // Encode parameter type. + getObjCEncodingForTypeImpl(T, S, true, true, 0, + true /*OutermostType*/, + false /*EncodingProperty*/, + false /*StructField*/, + Extended /*EncodeBlockParameters*/, + Extended /*EncodeClassNames*/); +} + /// getObjCEncodingForMethodDecl - Return the encoded type for this method /// declaration. bool ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, - std::string& S) const { + std::string& S, + bool Extended) const { // FIXME: This is not very efficient. - // Encode type qualifer, 'in', 'inout', etc. for the return type. - getObjCEncodingForTypeQualifier(Decl->getObjCDeclQualifier(), S); - // Encode result type. - getObjCEncodingForType(Decl->getResultType(), S); + // Encode return type. + getObjCEncodingForMethodParameter(Decl->getObjCDeclQualifier(), + Decl->getResultType(), S, Extended); // 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! @@ -4126,10 +4143,8 @@ bool ASTContext::getObjCEncodingForMethodDecl(const ObjCMethodDecl *Decl, PType = PVDecl->getType(); } else if (PType->isFunctionType()) PType = PVDecl->getType(); - // Process argument qualifiers for user supplied arguments; such as, - // 'in', 'inout', etc. - getObjCEncodingForTypeQualifier(PVDecl->getObjCDeclQualifier(), S); - getObjCEncodingForType(PType, S); + getObjCEncodingForMethodParameter(PVDecl->getObjCDeclQualifier(), + PType, S, Extended); S += charUnitsToString(ParmOffset); ParmOffset += getObjCEncodingTypeSize(PType); } @@ -4355,7 +4370,9 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, const FieldDecl *FD, bool OutermostType, bool EncodingProperty, - bool StructField) const { + bool StructField, + bool EncodeBlockParameters, + bool EncodeClassNames) const { if (T->getAs<BuiltinType>()) { if (FD && FD->isBitField()) return EncodeBitField(this, S, T, FD); @@ -4534,8 +4551,40 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, return; } - if (T->isBlockPointerType()) { + if (const BlockPointerType *BT = T->getAs<BlockPointerType>()) { S += "@?"; // Unlike a pointer-to-function, which is "^?". + if (EncodeBlockParameters) { + const FunctionType *FT = BT->getPointeeType()->getAs<FunctionType>(); + + S += '<'; + // Block return type + getObjCEncodingForTypeImpl(FT->getResultType(), S, + ExpandPointedToStructures, ExpandStructures, + FD, + false /* OutermostType */, + EncodingProperty, + false /* StructField */, + EncodeBlockParameters, + EncodeClassNames); + // Block self + S += "@?"; + // Block parameters + if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT)) { + for (FunctionProtoType::arg_type_iterator I = FPT->arg_type_begin(), + E = FPT->arg_type_end(); I && (I != E); ++I) { + getObjCEncodingForTypeImpl(*I, S, + ExpandPointedToStructures, + ExpandStructures, + FD, + false /* OutermostType */, + EncodingProperty, + false /* StructField */, + EncodeBlockParameters, + EncodeClassNames); + } + } + S += '>'; + } return; } @@ -4581,7 +4630,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, getObjCEncodingForTypeImpl(getObjCIdType(), S, ExpandPointedToStructures, ExpandStructures, FD); - if (FD || EncodingProperty) { + if (FD || EncodingProperty || EncodeClassNames) { // Note that we do extended encoding of protocol qualifer list // Only when doing ivar or property encoding. S += '"'; @@ -4610,7 +4659,8 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S, } S += '@'; - if (OPT->getInterfaceDecl() && (FD || EncodingProperty)) { + if (OPT->getInterfaceDecl() && + (FD || EncodingProperty || EncodeClassNames)) { S += '"'; S += OPT->getInterfaceDecl()->getIdentifier()->getName(); for (ObjCObjectPointerType::qual_iterator I = OPT->qual_begin(), |