Encoding for objectiive-c methods.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43481 91177308-0d34-0410-b5e6-96231b3b80d8
diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp
index bab2e0f..93d4232 100644
--- a/AST/ASTContext.cpp
+++ b/AST/ASTContext.cpp
@@ -153,6 +153,9 @@
ObjcIdType = QualType();
IdStructType = 0;
ObjcConstantStringType = QualType();
+
+ // void * type
+ VoidPtrTy = getPointerType(VoidTy);
}
//===----------------------------------------------------------------------===//
@@ -848,6 +851,60 @@
return false;
}
+/// getObjcEncodingTypeSize returns size of type for objective-c encoding
+/// purpose.
+int ASTContext::getObjcEncodingTypeSize(QualType type) {
+ SourceLocation Loc;
+ uint64_t sz = getTypeSize(type, Loc);
+
+ // Make all integer and enum types at least as large as an int
+ if (sz > 0 && type->isIntegralType())
+ sz = std::max(sz, getTypeSize(IntTy, Loc));
+ // Treat arrays as pointers, since that's how they're passed in.
+ else if (type->isArrayType())
+ sz = getTypeSize(VoidPtrTy, Loc);
+ return sz / getTypeSize(CharTy, Loc);
+}
+
+/// getObjcEncodingForMethodDecl - Return the encoded type for this method
+/// declaration.
+void ASTContext::getObjcEncodingForMethodDecl(ObjcMethodDecl *Decl,
+ std::string& S)
+{
+ // TODO: First encode type qualifer, 'in', 'inout', etc. for the return type.
+ // Encode result type.
+ getObjcEncodingForType(Decl->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, Loc) / getTypeSize(CharTy, Loc);
+ // The first two arguments (self and _cmd) are pointers; account for
+ // their size.
+ int ParmOffset = 2 * PtrSize;
+ int NumOfParams = Decl->getNumParams();
+ for (int i = 0; i < NumOfParams; i++) {
+ QualType PType = Decl->getParamDecl(i)->getType();
+ int sz = getObjcEncodingTypeSize (PType);
+ assert (sz > 0 && "getObjcEncodingForMethodDecl - Incomplete param type");
+ ParmOffset += sz;
+ }
+ S += llvm::utostr(ParmOffset);
+ S += "@0:";
+ S += llvm::utostr(PtrSize);
+
+ // Argument types.
+ ParmOffset = 2 * PtrSize;
+ for (int i = 0; i < NumOfParams; i++) {
+ QualType PType = Decl->getParamDecl(i)->getType();
+ // TODO: Process argument qualifiers for user supplied arguments; such as,
+ // 'in', 'inout', etc.
+ getObjcEncodingForType(PType, S);
+ S += llvm::utostr(ParmOffset);
+ ParmOffset += getObjcEncodingTypeSize(PType);
+ }
+}
+
void ASTContext::getObjcEncodingForType(QualType T, std::string& S) const
{
// FIXME: This currently doesn't encode:
diff --git a/AST/Type.cpp b/AST/Type.cpp
index f562376..02a9004 100644
--- a/AST/Type.cpp
+++ b/AST/Type.cpp
@@ -315,6 +315,16 @@
return false;
}
+bool Type::isIntegralType() const {
+ if (const BuiltinType *BT = dyn_cast<BuiltinType>(CanonicalType))
+ return BT->getKind() >= BuiltinType::Bool &&
+ BT->getKind() <= BuiltinType::LongLong;
+ if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
+ if (TT->getDecl()->getKind() == Decl::Enum)
+ return true;
+ return false;
+}
+
bool Type::isEnumeralType() const {
if (const TagType *TT = dyn_cast<TagType>(CanonicalType))
return TT->getDecl()->getKind() == Decl::Enum;