]> granicus.if.org Git - clang/commitdiff
Encoding for objectiive-c methods.
authorFariborz Jahanian <fjahanian@apple.com>
Mon, 29 Oct 2007 22:57:28 +0000 (22:57 +0000)
committerFariborz Jahanian <fjahanian@apple.com>
Mon, 29 Oct 2007 22:57:28 +0000 (22:57 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@43481 91177308-0d34-0410-b5e6-96231b3b80d8

AST/ASTContext.cpp
AST/Type.cpp
Driver/RewriteTest.cpp
clang.xcodeproj/project.pbxproj
include/clang/AST/ASTContext.h
include/clang/AST/Type.h

index bab2e0fcc383d87b0a79fe6396c5caa36cb7047d..93d4232bf2a59f8d43e3e98ab45eff8da2b4a610 100644 (file)
@@ -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:
index f562376de659d54d1db57f1e9565ad36ea69d100..02a90047da833795938bca937ae36d642060bb12 100644 (file)
@@ -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;
index 45dde83375535a2919bd2e6fcd735b6cb4b1ec83..c76b9eeba9bb2115e9781f3d8ac773d8c975a152 100644 (file)
@@ -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";
       }
index de41b4628d0c47ae944965792f26798c623eb63f..fe4cf8d85be8296188b8454e3723b21a50eb5906 100644 (file)
                08FB7793FE84155DC02AAC07 /* Project object */ = {
                        isa = PBXProject;
                        buildConfigurationList = 1DEB923508733DC60010E9CD /* Build configuration list for PBXProject "clang" */;
+                       compatibilityVersion = "Xcode 2.4";
                        hasScannedForEncodings = 1;
                        mainGroup = 08FB7794FE84155DC02AAC07 /* clang */;
                        projectDirPath = "";
index 9ac7b846dfd3cb745c3b1292cabd6fa4f8d99e96..3169726a76ef8792e31e26953c37ef2b0dfabb05 100644 (file)
@@ -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.
index 3140901b7e746f63fa036a5016223e36361fa587..59178b8d9bdb014fdb02cc4e8077b58167e0c16c 100644 (file)
@@ -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)