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

Fariborz Jahanian fjahanian at apple.com
Tue Dec 23 11:56:49 PST 2008


Author: fjahanian
Date: Tue Dec 23 13:56:47 2008
New Revision: 61383

URL: http://llvm.org/viewvc/llvm-project?rev=61383&view=rev
Log:
Lot more encoding work. We are closing the gap to
gcc compatibilty in all aspects of encoding now.

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

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

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Tue Dec 23 13:56:47 2008
@@ -300,6 +300,8 @@
   /// record field names are also encoded.
   void getObjCEncodingForType(QualType t, std::string &S, 
                               FieldDecl *Field=NULL) const;
+
+  void getLegacyIntegralTypeEncoding(QualType &t) const;
   
   // Put the string version of type qualifiers into S.
   void getObjCEncodingForTypeQualifier(Decl::ObjCDeclQualifier QT, 

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

==============================================================================
--- cfe/trunk/lib/AST/ASTContext.cpp (original)
+++ cfe/trunk/lib/AST/ASTContext.cpp Tue Dec 23 13:56:47 2008
@@ -1749,6 +1749,22 @@
   // FIXME: OBJCGC: weak & strong
 }
 
+/// getLegacyIntegralTypeEncoding -
+/// Another legacy compatibility encoding: 32-bit longs are encoded as 
+/// 'l' or 'L', but not always.  For typedefs, we need to use 
+/// 'i' or 'I' instead if encoding a struct field, or a pointer!
+///
+void ASTContext::getLegacyIntegralTypeEncoding (QualType &PointeeTy) const {
+  if (dyn_cast<TypedefType>(PointeeTy.getTypePtr())) {
+    if (const BuiltinType *BT = PointeeTy->getAsBuiltinType()) {
+      if (BT->getKind() == BuiltinType::ULong)
+        PointeeTy = UnsignedIntTy;
+        else if (BT->getKind() == BuiltinType::Long)
+          PointeeTy = IntTy;
+    }
+  }
+}
+
 void ASTContext::getObjCEncodingForType(QualType T, std::string& S,
                                         FieldDecl *Field) const {
   // We follow the behavior of gcc, expanding structures which are
@@ -1807,8 +1823,37 @@
   }
   else if (const PointerType *PT = T->getAsPointerType()) {
     QualType PointeeTy = PT->getPointeeType();
-    if (OutermostType && PointeeTy.isConstQualified())
-      S += 'r';
+    bool isReadOnly = false;
+    // For historical/compatibility reasons, the read-only qualifier of the
+    // pointee gets emitted _before_ the '^'.  The read-only qualifier of
+    // the pointer itself gets ignored, _unless_ we are looking at a typedef!
+    // Also, do not emit the 'r' for anything but the outermost type! 
+    if (dyn_cast<TypedefType>(T.getTypePtr())) {
+      if (OutermostType && T.isConstQualified()) {
+        isReadOnly = true;
+        S += 'r';
+      }
+    }
+    else if (OutermostType) {
+      QualType P = PointeeTy;
+      while (P->getAsPointerType())
+        P = P->getAsPointerType()->getPointeeType();
+      if (P.isConstQualified()) {
+        isReadOnly = true;
+        S += 'r';
+      }
+    }
+    if (isReadOnly) {
+      // Another legacy compatibility encoding. Some ObjC qualifier and type
+      // combinations need to be rearranged.
+      // Rewrite "in const" from "nr" to "rn"
+      const char * s = S.c_str();
+      int len = S.length();
+      if (len >= 2 && s[len-2] == 'n' && s[len-1] == 'r') {
+        std::string replace = "rn";
+        S.replace(S.end()-2, S.end(), replace);
+      }
+    }
     if (isObjCIdType(PointeeTy)) {
       S += '@';
       return;
@@ -1840,7 +1885,9 @@
     }
     
     S += '^';
-    getObjCEncodingForTypeImpl(PT->getPointeeType(), S, 
+    getLegacyIntegralTypeEncoding(PointeeTy);
+
+    getObjCEncodingForTypeImpl(PointeeTy, S, 
                                false, ExpandPointedToStructures, 
                                NULL);
   } else if (const ArrayType *AT =
@@ -1883,10 +1930,9 @@
           getObjCEncodingForTypeImpl(Field->getType(), S, false, true, 
                                      (*Field));
         } else {
-          // FIXME! Another legacy kludge: 32-bit longs are encoded as 
-          // 'l' or 'L', but not always.  For typedefs, we need to use 
-          // 'i' or 'I' instead if encoding a struct field, or a pointer! 
-          getObjCEncodingForTypeImpl(Field->getType(), S, false, true, 
+          QualType qt = Field->getType();
+          getLegacyIntegralTypeEncoding(qt);
+          getObjCEncodingForTypeImpl(qt, S, false, true, 
                                      FD);
         }
       }





More information about the cfe-commits mailing list