[cfe-commits] r43439 - in /cfe/trunk: AST/ASTContext.cpp CodeGen/CGExprScalar.cpp Driver/RewriteTest.cpp include/clang/AST/ASTContext.h

Anders Carlsson andersca at mac.com
Sun Oct 28 22:01:09 PDT 2007


Author: andersca
Date: Mon Oct 29 00:01:08 2007
New Revision: 43439

URL: http://llvm.org/viewvc/llvm-project?rev=43439&view=rev
Log:
Add (partial) support for @encode.

Modified:
    cfe/trunk/AST/ASTContext.cpp
    cfe/trunk/CodeGen/CGExprScalar.cpp
    cfe/trunk/Driver/RewriteTest.cpp
    cfe/trunk/include/clang/AST/ASTContext.h

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

==============================================================================
--- cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/trunk/AST/ASTContext.cpp Mon Oct 29 00:01:08 2007
@@ -16,6 +16,8 @@
 #include "clang/AST/DeclObjC.h"
 #include "clang/Basic/TargetInfo.h"
 #include "llvm/ADT/SmallVector.h"
+#include "llvm/ADT/StringExtras.h"
+
 using namespace clang;
 
 enum FloatingRank {
@@ -835,6 +837,104 @@
   return getTagDeclType(CFConstantStringTypeDecl);
 }
 
+static bool isTypeTypedefedAsBOOL(QualType T)
+{
+  if (const PointerType *NCPT = T->getAsPointerType())
+    if (const TypedefType *TT = dyn_cast<TypedefType>(NCPT->getPointeeType()))
+      if (!strcmp(TT->getDecl()->getName(), "BOOL"))
+        return true;
+        
+  return false;
+}
+
+void ASTContext::getObjcEncodingForType(QualType T, std::string& S) const
+{
+  QualType Ty = T.getCanonicalType();
+
+  if (const BuiltinType *BT = Ty->getAsBuiltinType()) {
+    char encoding;
+    switch (BT->getKind()) {
+    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;
+    default:
+      assert(0 && "Unhandled builtin type kind");          
+    }
+    
+    S += encoding;
+  } else if (const PointerType *PT = Ty->getAsPointerType()) {
+    QualType PointeeTy = PT->getPointeeType();
+    
+    if (PointeeTy->isCharType()) {
+      // char pointer types should be encoded as '*' unless it is a
+      // type that has been typedef'd to 'BOOL'.
+      if (isTypeTypedefedAsBOOL(T)) {
+        S += '*';
+        return;
+      }
+    }
+    
+    S += '^';
+    getObjcEncodingForType(PT->getPointeeType(), S);
+  } else if (const ArrayType *AT = Ty->getAsArrayType()) {
+    S += '[';
+    
+    if (const ConstantArrayType *CAT = dyn_cast<ConstantArrayType>(AT))
+      S += llvm::utostr(CAT->getSize().getZExtValue());
+    else
+      assert(0 && "Unhandled array type!");
+    
+    getObjcEncodingForType(AT->getElementType(), S);
+    S += ']';
+  } else
+    fprintf(stderr, "@encode for type %s not implemented!\n", 
+            Ty.getAsString().c_str());
+}
+
 void ASTContext::setBuiltinVaListType(QualType T)
 {
   assert(BuiltinVaListType.isNull() && "__builtin_va_list type already set!");

Modified: cfe/trunk/CodeGen/CGExprScalar.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/CodeGen/CGExprScalar.cpp?rev=43439&r1=43438&r2=43439&view=diff

==============================================================================
--- cfe/trunk/CodeGen/CGExprScalar.cpp (original)
+++ cfe/trunk/CodeGen/CGExprScalar.cpp Mon Oct 29 00:01:08 2007
@@ -16,6 +16,7 @@
 #include "clang/AST/AST.h"
 #include "llvm/Constants.h"
 #include "llvm/Function.h"
+#include "llvm/GlobalVariable.h"
 #include "llvm/Intrinsics.h"
 #include "llvm/Support/Compiler.h"
 using namespace clang;
@@ -262,6 +263,7 @@
   Value *VisitObjCStringLiteral(const ObjCStringLiteral *E) {
     return CGF.EmitObjCStringLiteral(E);
   }
+  Value *VisitObjCEncodeExpr(const ObjCEncodeExpr *E);
 };
 }  // end anonymous namespace.
 
@@ -917,6 +919,23 @@
   return V;
 }
 
+Value *ScalarExprEmitter::VisitObjCEncodeExpr(const ObjCEncodeExpr *E)
+{
+  std::string str;
+  
+  CGF.getContext().getObjcEncodingForType(E->getEncodedType(), str);
+  
+  llvm::Constant *C = llvm::ConstantArray::get(str);
+  C = new llvm::GlobalVariable(C->getType(), true, 
+                               llvm::GlobalValue::InternalLinkage,
+                               C, ".str", &CGF.CGM.getModule());
+  llvm::Constant *Zero = llvm::Constant::getNullValue(llvm::Type::Int32Ty);
+  llvm::Constant *Zeros[] = { Zero, Zero };
+  C = llvm::ConstantExpr::getGetElementPtr(C, Zeros, 2);
+  
+  return C;
+}
+
 //===----------------------------------------------------------------------===//
 //                         Entry Point into this File
 //===----------------------------------------------------------------------===//

Modified: cfe/trunk/Driver/RewriteTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/RewriteTest.cpp?rev=43439&r1=43438&r2=43439&view=diff

==============================================================================
--- cfe/trunk/Driver/RewriteTest.cpp (original)
+++ cfe/trunk/Driver/RewriteTest.cpp Mon Oct 29 00:01:08 2007
@@ -329,7 +329,10 @@
 Stmt *RewriteTest::RewriteAtEncode(ObjCEncodeExpr *Exp) {
   // Create a new string expression.
   QualType StrType = Context->getPointerType(Context->CharTy);
-  Expr *Replacement = new StringLiteral("foo", 3, false, StrType, 
+  std::string StrEncoding;
+  Context->getObjcEncodingForType(Exp->getEncodedType(), StrEncoding);
+  Expr *Replacement = new StringLiteral(StrEncoding.c_str(),
+                                        StrEncoding.length(), false, StrType, 
                                         SourceLocation(), SourceLocation());
   Rewrite.ReplaceStmt(Exp, Replacement);
   delete Exp;

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

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Mon Oct 29 00:01:08 2007
@@ -171,6 +171,9 @@
     return ObjcConstantStringType; 
   }
 
+  // Return the ObjC type encoding for a given type.
+  void getObjcEncodingForType(QualType t, std::string &S) const;
+    
   // This setter/getter repreents the ObjC 'id' type. It is setup lazily, by
   // Sema.
   void setObjcIdType(TypedefDecl *Decl);





More information about the cfe-commits mailing list