[cfe-commits] r57685 - in /cfe/trunk: include/clang/AST/ASTContext.h lib/AST/ASTContext.cpp lib/CodeGen/CGObjCMac.cpp

Daniel Dunbar daniel at zuster.org
Fri Oct 17 09:17:38 PDT 2008


Author: ddunbar
Date: Fri Oct 17 11:17:37 2008
New Revision: 57685

URL: http://llvm.org/viewvc/llvm-project?rev=57685&view=rev
Log:
More Obj-C type encoding improvements.
 - Encode unions and bit-fields correctly.
 - Accept option to name record fields (used for NeXT runtime).

Modified:
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/lib/AST/ASTContext.cpp
    cfe/trunk/lib/CodeGen/CGObjCMac.cpp

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

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Fri Oct 17 11:17:37 2008
@@ -273,9 +273,12 @@
   //// This gets the struct used to keep track of fast enumerations.
   QualType getObjCFastEnumerationStateType();
   
-  // Return the ObjC type encoding for a given type.
+  /// getObjCEncodingForType - Emit the ObjC type encoding for the
+  /// given type into \arg S. If \arg NameFields is specified then
+  /// record field names are also encoded.
   void getObjCEncodingForType(QualType t, std::string &S, 
-                              llvm::SmallVector<const RecordType*,8> &RT) const;
+                              llvm::SmallVector<const RecordType*,8> &RT,
+                              bool NameFields=false) const;
   
   // Put the string version of type qualifiers into S.
   void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT, 
@@ -478,7 +481,8 @@
   void getObjCEncodingForTypeImpl(QualType t, std::string &S, 
                                   bool ExpandPointedToStructures,
                                   bool ExpandStructures,
-                              llvm::SmallVector<const RecordType*,8> &RT) const;
+                              llvm::SmallVector<const RecordType*,8> &RT,
+                                  bool NameFields) const;
   
 };
   

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

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Fri Oct 17 11:17:37 2008
@@ -1594,26 +1594,20 @@
 }
 
 void ASTContext::getObjCEncodingForType(QualType T, std::string& S,
-                         llvm::SmallVector<const RecordType*,8> &ERType) const {
+                         llvm::SmallVector<const RecordType*,8> &ERType,
+                                        bool NameFields) 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, ERType);
+  getObjCEncodingForTypeImpl(T, S, true, true, ERType, NameFields);
 }
 
 void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string& S,
                                             bool ExpandPointedToStructures,
                                             bool ExpandStructures,
-                         llvm::SmallVector<const RecordType*,8> &ERType) const {
-  // FIXME: This currently doesn't encode:
-  // @ An object (whether statically typed or typed id)
-  // # A class object (Class)
-  // : A method selector (SEL)
-  // {name=type...} A structure
-  // (name=type...) A union
-  // bnum A bit field of num bits
-  
+                         llvm::SmallVector<const RecordType*,8> &ERType,
+                                            bool NameFields) const {
   if (const BuiltinType *BT = T->getAsBuiltinType()) {
     char encoding;
     switch (BT->getKind()) {
@@ -1643,7 +1637,7 @@
     // Treat id<P...> same as 'id' for encoding purposes.
     return getObjCEncodingForTypeImpl(getObjCIdType(), S, 
                                       ExpandPointedToStructures,
-                                      ExpandStructures, ERType);    
+                                      ExpandStructures, ERType, NameFields);    
   }
   else if (const PointerType *PT = T->getAsPointerType()) {
     QualType PointeeTy = PT->getPointeeType();
@@ -1669,7 +1663,8 @@
     
     S += '^';
     getObjCEncodingForTypeImpl(PT->getPointeeType(), S, 
-                               false, ExpandPointedToStructures, ERType);
+                               false, ExpandPointedToStructures, 
+                               ERType, NameFields);
   } else if (const ArrayType *AT =
                // Ignore type qualifiers etc.
                dyn_cast<ArrayType>(T->getCanonicalTypeInternal())) {
@@ -1681,13 +1676,13 @@
       assert(0 && "Unhandled array type!");
     
     getObjCEncodingForTypeImpl(AT->getElementType(), S, 
-                               false, ExpandStructures, ERType);
+                               false, ExpandStructures, ERType, NameFields);
     S += ']';
   } else if (T->getAsFunctionType()) {
     S += '?';
   } else if (const RecordType *RTy = T->getAsRecordType()) {
     RecordDecl *RDecl = RTy->getDecl();
-    S += '{';
+    S += RDecl->isUnion() ? '(' : '{';
     // Anonymous structures print as '?'
     if (const IdentifierInfo *II = RDecl->getIdentifier()) {
       S += II->getName();
@@ -1704,13 +1699,31 @@
       ERType.push_back(RTy);
       S += '=';
       for (int i = 0; i < RDecl->getNumMembers(); i++) {
-        FieldDecl *field = RDecl->getMember(i);
-        getObjCEncodingForTypeImpl(field->getType(), S, false, true, ERType);
+        FieldDecl *FD = RDecl->getMember(i);
+        if (NameFields) {
+          S += '"';
+          S += FD->getName();
+          S += '"';
+        }
+        
+        // Special case bit-fields.
+        if (const Expr *E = FD->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);
+        } else {
+          getObjCEncodingForTypeImpl(FD->getType(), S, false, true,
+                                     ERType, NameFields);
+        }
       }
       assert(ERType.back() == RTy && "Record Type stack mismatch.");
       ERType.pop_back();
     }
-    S += '}';
+    S += RDecl->isUnion() ? ')' : '}';
   } else if (T->isEnumeralType()) {
     S += 'i';
   } else if (T->isBlockPointerType()) {

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

==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjCMac.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjCMac.cpp Fri Oct 17 11:17:37 2008
@@ -1271,7 +1271,8 @@
     llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
     Ivar[0] = GetMethodVarName(V->getIdentifier());
     CGM.getContext().getObjCEncodingForType(V->getType(), TypeStr,
-                                            EncodingRecordTypes);
+                                            EncodingRecordTypes,
+                                            true);
     Ivar[1] = GetMethodVarType(TypeStr);
     Ivar[2] = llvm::ConstantInt::get(ObjCTypes.IntTy, Offset);
     Ivars.push_back(llvm::ConstantStruct::get(ObjCTypes.IvarTy,





More information about the cfe-commits mailing list