[cfe-commits] r61268 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/CodeGen/CGObjCMac.cpp test/CodeGenObjC/encode-test.m

Fariborz Jahanian fjahanian at apple.com
Fri Dec 19 15:34:54 PST 2008


Author: fjahanian
Date: Fri Dec 19 17:34:38 2008
New Revision: 61268

URL: http://llvm.org/viewvc/llvm-project?rev=61268&view=rev
Log:
More encoding support. This time for
@encode of classes and bitfields.

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp
    cfe/trunk/test/CodeGenObjC/encode-test.m

Modified: cfe/trunk/include/clang/AST/ASTContext.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTContext.h?rev=61268&r1=61267&r2=61268&view=diff

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Fri Dec 19 17:34:38 2008
@@ -299,7 +299,7 @@
   /// given type into \arg S. If \arg NameFields is specified then
   /// record field names are also encoded.
   void getObjCEncodingForType(QualType t, std::string &S, 
-                              bool NameFields=false) const;
+                              FieldDecl *Field=NULL) const;
   
   // Put the string version of type qualifiers into S.
   void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT, 
@@ -542,7 +542,7 @@
   void getObjCEncodingForTypeImpl(QualType t, std::string &S, 
                                   bool ExpandPointedToStructures,
                                   bool ExpandStructures,
-                                  bool NameFields) const;
+                                  FieldDecl *Field) const;
   
 };
   

Modified: cfe/trunk/lib/AST/ASTContext.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTContext.cpp?rev=61268&r1=61267&r2=61268&view=diff

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Dec 19 17:34:38 2008
@@ -1734,48 +1734,58 @@
 }
 
 void ASTContext::getObjCEncodingForType(QualType T, std::string& S,
-                                        bool NameFields) const {
+                                        FieldDecl *Field) const {
   // We follow the behavior of gcc, expanding structures which are
   // directly pointed to, and expanding embedded structures. Note that
   // these rules are sufficient to prevent recursive encoding of the
   // same type.
-  getObjCEncodingForTypeImpl(T, S, true, true, NameFields);
+  getObjCEncodingForTypeImpl(T, S, true, true, Field);
 }
 
 void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
                                             bool ExpandPointedToStructures,
                                             bool ExpandStructures,
-                                            bool NameFields) const {
+                                            FieldDecl *FD) const {
   if (const BuiltinType *BT = T->getAsBuiltinType()) {
-    char encoding;
-    switch (BT->getKind()) {
-    default: assert(0 && "Unhandled builtin type kind");          
-    case BuiltinType::Void:       encoding = 'v'; break;
-    case BuiltinType::Bool:       encoding = 'B'; break;
-    case BuiltinType::Char_U:
-    case BuiltinType::UChar:      encoding = 'C'; break;
-    case BuiltinType::UShort:     encoding = 'S'; break;
-    case BuiltinType::UInt:       encoding = 'I'; break;
-    case BuiltinType::ULong:      encoding = 'L'; break;
-    case BuiltinType::ULongLong:  encoding = 'Q'; break;
-    case BuiltinType::Char_S:
-    case BuiltinType::SChar:      encoding = 'c'; break;
-    case BuiltinType::Short:      encoding = 's'; break;
-    case BuiltinType::Int:        encoding = 'i'; break;
-    case BuiltinType::Long:       encoding = 'l'; break;
-    case BuiltinType::LongLong:   encoding = 'q'; break;
-    case BuiltinType::Float:      encoding = 'f'; break;
-    case BuiltinType::Double:     encoding = 'd'; break;
-    case BuiltinType::LongDouble: encoding = 'd'; break;
-    }
+    if (FD && FD->isBitField()) {
+      const Expr *E = FD->getBitWidth();
+      assert(E && "bitfield width not there - getObjCEncodingForTypeImpl");
+      ASTContext *Ctx = const_cast<ASTContext*>(this);
+      unsigned N = E->getIntegerConstantExprValue(*Ctx).getZExtValue();
+      S += 'b';
+      S += llvm::utostr(N);
+    }
+    else {
+      char encoding;
+      switch (BT->getKind()) {
+      default: assert(0 && "Unhandled builtin type kind");          
+      case BuiltinType::Void:       encoding = 'v'; break;
+      case BuiltinType::Bool:       encoding = 'B'; break;
+      case BuiltinType::Char_U:
+      case BuiltinType::UChar:      encoding = 'C'; break;
+      case BuiltinType::UShort:     encoding = 'S'; break;
+      case BuiltinType::UInt:       encoding = 'I'; break;
+      case BuiltinType::ULong:      encoding = 'L'; break;
+      case BuiltinType::ULongLong:  encoding = 'Q'; break;
+      case BuiltinType::Char_S:
+      case BuiltinType::SChar:      encoding = 'c'; break;
+      case BuiltinType::Short:      encoding = 's'; break;
+      case BuiltinType::Int:        encoding = 'i'; break;
+      case BuiltinType::Long:       encoding = 'l'; break;
+      case BuiltinType::LongLong:   encoding = 'q'; break;
+      case BuiltinType::Float:      encoding = 'f'; break;
+      case BuiltinType::Double:     encoding = 'd'; break;
+      case BuiltinType::LongDouble: encoding = 'd'; break;
+      }
     
-    S += encoding;
+      S += encoding;
+    }
   }
   else if (T->isObjCQualifiedIdType()) {
     // Treat id<P...> same as 'id' for encoding purposes.
     return getObjCEncodingForTypeImpl(getObjCIdType(), S, 
                                       ExpandPointedToStructures,
-                                      ExpandStructures, NameFields);    
+                                      ExpandStructures, FD);    
   }
   else if (const PointerType *PT = T->getAsPointerType()) {
     QualType PointeeTy = PT->getPointeeType();
@@ -1810,7 +1820,7 @@
     S += '^';
     getObjCEncodingForTypeImpl(PT->getPointeeType(), S, 
                                false, ExpandPointedToStructures, 
-                               false);
+                               NULL);
   } else if (const ArrayType *AT =
                // Ignore type qualifiers etc.
                dyn_cast<ArrayType>(T->getCanonicalTypeInternal())) {
@@ -1822,7 +1832,7 @@
       assert(0 && "Unhandled array type!");
     
     getObjCEncodingForTypeImpl(AT->getElementType(), S, 
-                               false, ExpandStructures, NameFields);
+                               false, ExpandStructures, FD);
     S += ']';
   } else if (T->getAsFunctionType()) {
     S += '?';
@@ -1840,24 +1850,19 @@
       for (RecordDecl::field_iterator Field = RDecl->field_begin(),
                                    FieldEnd = RDecl->field_end();
            Field != FieldEnd; ++Field) {
-        if (NameFields) {
+        if (FD) {
           S += '"';
           S += Field->getNameAsString();
           S += '"';
         }
         
         // Special case bit-fields.
-        if (const Expr *E = Field->getBitWidth()) {
-          // FIXME: Fix constness.
-          ASTContext *Ctx = const_cast<ASTContext*>(this);
-          unsigned N = E->getIntegerConstantExprValue(*Ctx).getZExtValue();
-          // FIXME: Obj-C is losing information about the type size
-          // here. Investigate if this is a problem.
-          S += 'b';
-          S += llvm::utostr(N);
+        if (Field->isBitField()) {
+          getObjCEncodingForTypeImpl(Field->getType(), S, false, true, 
+                                     (*Field));
         } else {
           getObjCEncodingForTypeImpl(Field->getType(), S, false, true, 
-                                     NameFields);
+                                     FD);
         }
       }
     }
@@ -1866,7 +1871,26 @@
     S += 'i';
   } else if (T->isBlockPointerType()) {
     S += '^'; // This type string is the same as general pointers.
-  } else
+  } else if (T->isObjCInterfaceType()) {
+    // @encode(class_name)
+    ObjCInterfaceDecl *OI = T->getAsObjCInterfaceType()->getDecl();
+    S += '{';
+    const IdentifierInfo *II = OI->getIdentifier();
+    S += II->getName();
+    S += '=';
+    std::vector<FieldDecl*> RecFields;
+    CollectObjCIvars(OI, RecFields);
+    for (unsigned int i = 0; i != RecFields.size(); i++) {
+      if (RecFields[i]->isBitField())
+        getObjCEncodingForTypeImpl(RecFields[i]->getType(), S, false, true, 
+                                   RecFields[i]);
+      else
+        getObjCEncodingForTypeImpl(RecFields[i]->getType(), S, false, true, 
+                                   FD);
+    }
+    S += '}';
+  }
+  else
     assert(0 && "@encode for type not implemented!");
 }
 

Modified: cfe/trunk/lib/CodeGen/CGObjCMac.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjCMac.cpp?rev=61268&r1=61267&r2=61268&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Fri Dec 19 17:34:38 2008
@@ -1336,7 +1336,7 @@
       Layout->getElementOffset(CGM.getTypes().getLLVMFieldNo(Field));
     std::string TypeStr;
     Ivar[0] = GetMethodVarName(V->getIdentifier());
-    CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr, true);
+    CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr, Field);
     Ivar[1] = GetMethodVarType(TypeStr);
     Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
     Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy, Ivar));

Modified: cfe/trunk/test/CodeGenObjC/encode-test.m
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenObjC/encode-test.m?rev=61268&r1=61267&r2=61268&view=diff

==============================================================================
--- cfe/trunk/test/CodeGenObjC/encode-test.m (original)
+++ cfe/trunk/test/CodeGenObjC/encode-test.m Fri Dec 19 17:34:38 2008
@@ -1,5 +1,6 @@
 // RUN: clang -fnext-runtime -emit-llvm -o %t %s &&
-// RUN: grep -e "\^{Innermost=CC}" %t | count 1
+// RUN: grep -e "\^{Innermost=CC}" %t | count 1 &&
+// RUN: grep -e "{Derived=#ib32b8b3b8sb16b8b8b2b8ccb6}" %t | count 1
 
 @class Int1;
 
@@ -15,3 +16,40 @@
 
 @implementation Int1
 @end
+
+ at interface Base
+{
+    struct objc_class *isa;
+    int full;
+    int full2: 32;
+    int _refs: 8;
+    int field2: 3;
+    unsigned f3: 8;
+    short cc;
+    unsigned g: 16;
+    int r2: 8;
+    int r3: 8;
+    int r4: 2;
+    int r5: 8;
+    char c;
+}
+ at end
+
+ at interface Derived: Base
+{
+    char d;
+    int _field3: 6;
+}
+ at end
+
+ at implementation Base
+ at end
+
+ at implementation Derived
+ at end
+
+int main()
+{
+	const char *en = @encode(Derived);
+}
+





More information about the cfe-commits mailing list