aboutsummaryrefslogtreecommitdiff
path: root/lib/AST/ASTContext.cpp
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@apple.com>2011-11-30 01:57:58 +0000
committerBob Wilson <bob.wilson@apple.com>2011-11-30 01:57:58 +0000
commitdc8dab6fabf4bfd4f4b94bf572ac3342a5bbfcd7 (patch)
treee07864cea78427256faac4556a5f09178139d96d /lib/AST/ASTContext.cpp
parentdff466c0791465f929a1d8cd551d4c84b360ba32 (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.cpp76
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(),