diff options
author | Fariborz Jahanian <fjahanian@apple.com> | 2007-10-29 22:57:28 +0000 |
---|---|---|
committer | Fariborz Jahanian <fjahanian@apple.com> | 2007-10-29 22:57:28 +0000 |
commit | 33e1d64ab5cd5d27f8530ccd056191fe2c9f3f2e (patch) | |
tree | 80a0061a74edcb18c406b150eeb290dfd5aac07a | |
parent | 10b945c9ee27595f8710aba4b3447d206b354ca1 (diff) |
Encoding for objectiive-c methods.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43481 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | AST/ASTContext.cpp | 57 | ||||
-rw-r--r-- | AST/Type.cpp | 10 | ||||
-rw-r--r-- | Driver/RewriteTest.cpp | 35 | ||||
-rw-r--r-- | clang.xcodeproj/project.pbxproj | 1 | ||||
-rw-r--r-- | include/clang/AST/ASTContext.h | 9 | ||||
-rw-r--r-- | include/clang/AST/Type.h | 2 |
6 files changed, 100 insertions, 14 deletions
diff --git a/AST/ASTContext.cpp b/AST/ASTContext.cpp index bab2e0fcc3..93d4232bf2 100644 --- a/AST/ASTContext.cpp +++ b/AST/ASTContext.cpp @@ -153,6 +153,9 @@ void ASTContext::InitBuiltinTypes() { ObjcIdType = QualType(); IdStructType = 0; ObjcConstantStringType = QualType(); + + // void * type + VoidPtrTy = getPointerType(VoidTy); } //===----------------------------------------------------------------------===// @@ -848,6 +851,60 @@ static bool isTypeTypedefedAsBOOL(QualType T) 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 f562376de6..02a90047da 100644 --- a/AST/Type.cpp +++ b/AST/Type.cpp @@ -315,6 +315,16 @@ bool Type::isIntegerType() const { 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; diff --git a/Driver/RewriteTest.cpp b/Driver/RewriteTest.cpp index 45dde83375..c76b9eeba9 100644 --- a/Driver/RewriteTest.cpp +++ b/Driver/RewriteTest.cpp @@ -495,15 +495,20 @@ void RewriteTest::RewriteObjcMethodsMetaData(ObjcMethodDecl **Methods, Result += "\t,{{(SEL)\""; Result += Methods[0]->getSelector().getName().c_str(); - Result += "\", \"\", 0}\n"; - + std::string MethodTypeString; + Context->getObjcEncodingForMethodDecl(Methods[0], MethodTypeString); + Result += "\", \""; + Result += MethodTypeString; + Result += "\", 0}\n"; for (int i = 1; i < NumMethods; i++) { - // TODO: 1) method selector name may hav to go into their own section - // 2) encode method types for use here (which may have to go into - // __meth_var_types section, 3) Need method address as 3rd initializer. + // TODO: Need method address as 3rd initializer. Result += "\t ,{(SEL)\""; Result += Methods[i]->getSelector().getName().c_str(); - Result += "\", \"\", 0}\n"; + std::string MethodTypeString; + Context->getObjcEncodingForMethodDecl(Methods[i], MethodTypeString); + Result += "\", \""; + Result += MethodTypeString; + Result += "\", 0}\n"; } Result += "\t }\n};\n"; } @@ -559,12 +564,13 @@ void RewriteTest::RewriteObjcProtocolsMetaData(ObjcProtocolDecl **Protocols, Result += "\", \"\"}\n"; for (int i = 1; i < NumMethods; i++) { - // TODO: 1) method selector name may hav to go into their own section - // 2) encode method types for use here (which may have to go into - // __meth_var_types section. Result += "\t ,{(SEL)\""; Result += Methods[i]->getSelector().getName().c_str(); - Result += "\", \"\"}\n"; + std::string MethodTypeString; + Context->getObjcEncodingForMethodDecl(Methods[i], MethodTypeString); + Result += "\", \""; + Result += MethodTypeString; + Result += "\"}\n"; } Result += "\t }\n};\n"; } @@ -586,12 +592,13 @@ void RewriteTest::RewriteObjcProtocolsMetaData(ObjcProtocolDecl **Protocols, Result += "\", \"\"}\n"; for (int i = 1; i < NumMethods; i++) { - // TODO: 1) method selector name may hav to go into their own section - // 2) encode method types for use here (which may have to go into - // __meth_var_types section. Result += "\t ,{(SEL)\""; Result += Methods[i]->getSelector().getName().c_str(); - Result += "\", \"\"}\n"; + std::string MethodTypeString; + Context->getObjcEncodingForMethodDecl(Methods[i], MethodTypeString); + Result += "\", \""; + Result += MethodTypeString; + Result += "\"}\n"; } Result += "\t }\n};\n"; } diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index de41b4628d..fe4cf8d85b 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -756,6 +756,7 @@ 08FB7793FE84155DC02AAC07 /* Project object */ = { isa = PBXProject; buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */; + compatibilityVersion = "Xcode 2.4"; hasScannedForEncodings = 1; mainGroup = 08FB7794FE84155DC02AAC07 /* clang */; projectDirPath = ""; diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index 9ac7b846df..3169726a76 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -77,6 +77,7 @@ public: QualType UnsignedLongLongTy; QualType FloatTy, DoubleTy, LongDoubleTy; QualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy; + QualType VoidPtrTy; ASTContext(SourceManager &SM, TargetInfo &t, IdentifierTable &idents, SelectorTable &sels) : @@ -173,6 +174,14 @@ public: // Return the ObjC type encoding for a given type. void getObjcEncodingForType(QualType t, std::string &S) const; + + /// getObjcEncodingForMethodDecl - Return the encoded type for this method + /// declaration. + void getObjcEncodingForMethodDecl(ObjcMethodDecl *Decl, std::string &S); + + /// getObjcEncodingTypeSize returns size of type for objective-c encoding + /// purpose. + int getObjcEncodingTypeSize(QualType t); // This setter/getter repreents the ObjC 'id' type. It is setup lazily, by // Sema. diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h index 3140901b7e..59178b8d9b 100644 --- a/include/clang/AST/Type.h +++ b/include/clang/AST/Type.h @@ -34,6 +34,7 @@ namespace clang { class EnumDecl; class ObjcInterfaceDecl; class ObjcProtocolDecl; + class ObjcMethodDecl; class Expr; class SourceLocation; class PointerType; @@ -273,6 +274,7 @@ public: bool isEnumeralType() const; bool isBooleanType() const; bool isCharType() const; + bool isIntegralType() const; /// Floating point categories. bool isRealFloatingType() const; // C99 6.2.5p10 (float, double, long double) |