[cfe-commits] r48383 - /cfe/trunk/Driver/RewriteTest.cpp

Steve Naroff snaroff at apple.com
Fri Mar 14 17:55:57 PDT 2008


Author: snaroff
Date: Fri Mar 14 19:55:56 2008
New Revision: 48383

URL: http://llvm.org/viewvc/llvm-project?rev=48383&view=rev
Log:
Remove ObjC rewriter dependency on GCC's __builtin___CFStringMakeConstantString.

Modified:
    cfe/trunk/Driver/RewriteTest.cpp

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

==============================================================================
--- cfe/trunk/Driver/RewriteTest.cpp (original)
+++ cfe/trunk/Driver/RewriteTest.cpp Fri Mar 14 19:55:56 2008
@@ -52,6 +52,8 @@
     llvm::SmallVector<int, 8> ObjCBcLabelNo;
     llvm::SmallVector<const RecordType *, 8> EncodingRecordTypes;
     
+    unsigned NumObjCStringLiterals;
+    
     FunctionDecl *MsgSendFunctionDecl;
     FunctionDecl *MsgSendSuperFunctionDecl;
     FunctionDecl *MsgSendStretFunctionDecl;
@@ -74,6 +76,7 @@
     // Needed for super.
     ObjCMethodDecl *CurMethodDecl;
     RecordDecl *SuperStructDecl;
+    RecordDecl *ConstantStringDecl;
     
     // Needed for header files being rewritten
     bool IsHeader;
@@ -149,6 +152,7 @@
     bool needToScanForQualifiers(QualType T);
     ObjCInterfaceDecl *isSuperReceiver(Expr *recExpr);
     QualType getSuperStructType();
+    QualType getConstantStringStructType();
     
     // Expression Rewriting.
     Stmt *RewriteFunctionBodyOrGlobalInitializer(Stmt *S);
@@ -179,7 +183,6 @@
     void SynthMsgSendSuperStretFunctionDecl();
     void SynthGetClassFunctionDecl();
     void SynthGetMetaClassFunctionDecl();
-    void SynthCFStringFunctionDecl();
     void SynthSelGetUidFunctionDecl();
     void SynthGetProtocolFunctionDecl();
     void SynthSuperContructorFunctionDecl();
@@ -252,6 +255,7 @@
   SuperStructDecl = 0;
   BcLabelCount = 0;
   SuperContructorFunctionDecl = 0;
+  NumObjCStringLiterals = 0;
   
   // Get the ID and start/end of the main file.
   MainFileID = SM->getMainFileID();
@@ -315,6 +319,19 @@
   S += "unsigned long extra[5];\n};\n";
   S += "#define __FASTENUMERATIONSTATE\n";
   S += "#endif\n";
+  S += "#ifndef __NSCONSTANTSTRINGIMPL\n";
+  S += "struct __NSConstantStringImpl {\n";
+  S += "  struct objc_object *isa;\n";
+  S += "  int flags;\n";
+  S += "  char *str;\n";
+  S += "  long length;\n";
+  S += "  __NSConstantStringImpl(char *s, long l) :\n";
+  S += "  flags(0), str(s), length(l)\n";
+  S += "    { extern struct objc_object *_NSConstantStringClassReference;\n";
+  S += "      isa = _NSConstantStringClassReference; }\n";
+  S += "};\n";
+  S += "#define __NSCONSTANTSTRINGIMPL\n";
+  S += "#endif\n";
 #if 0
   if (LangOpts.Microsoft) 
     S += "#define __attribute__(X)\n";
@@ -1707,74 +1724,37 @@
                                               FunctionDecl::Extern, false, 0);
 }
 
-// SynthCFStringFunctionDecl - id __builtin___CFStringMakeConstantString(const char *name);
-void RewriteTest::SynthCFStringFunctionDecl() {
-  IdentifierInfo *getClassIdent = &Context->Idents.get("__builtin___CFStringMakeConstantString");
-  llvm::SmallVector<QualType, 16> ArgTys;
-  ArgTys.push_back(Context->getPointerType(
-                     Context->CharTy.getQualifiedType(QualType::Const)));
-  QualType getClassType = Context->getFunctionType(Context->getObjCIdType(),
-                                                   &ArgTys[0], ArgTys.size(),
-                                                   false /*isVariadic*/);
-  CFStringFunctionDecl = new FunctionDecl(SourceLocation(), 
-                                          getClassIdent, getClassType,
-                                          FunctionDecl::Extern, false, 0);
-}
-
 Stmt *RewriteTest::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
-#if 1
-  // This rewrite is specific to GCC, which has builtin support for CFString.
-  if (!CFStringFunctionDecl)
-    SynthCFStringFunctionDecl();
-  // Create a call to __builtin___CFStringMakeConstantString("cstr").
-  llvm::SmallVector<Expr*, 8> StrExpr;
-  StrExpr.push_back(Exp->getString());
-  CallExpr *call = SynthesizeCallToFunctionDecl(CFStringFunctionDecl,
-                                                &StrExpr[0], StrExpr.size());
-  // cast to NSConstantString *
-  CastExpr *cast = new CastExpr(Exp->getType(), call, SourceLocation());
-  ReplaceStmt(Exp, cast);
-  delete Exp;
-  return cast;
-#else
-  assert(ConstantStringClassReference && "Can't find constant string reference");
-  llvm::SmallVector<Expr*, 4> InitExprs;
-  
-  // Synthesize "(Class)&_NSConstantStringClassReference"
-  DeclRefExpr *ClsRef = new DeclRefExpr(ConstantStringClassReference,
-                                        ConstantStringClassReference->getType(),
-                                        SourceLocation());
-  QualType expType = Context->getPointerType(ClsRef->getType());
-  UnaryOperator *Unop = new UnaryOperator(ClsRef, UnaryOperator::AddrOf,
-                                          expType, SourceLocation());
-  CastExpr *cast = new CastExpr(Context->getObjCClassType(), Unop, 
-                                SourceLocation());
-  InitExprs.push_back(cast); // set the 'isa'.
-  InitExprs.push_back(Exp->getString()); // set "char *bytes".
-  unsigned IntSize = static_cast<unsigned>(
-      Context->getTypeSize(Context->IntTy, Exp->getLocStart()));
-  llvm::APInt IntVal(IntSize, Exp->getString()->getByteLength());
-  IntegerLiteral *len = new IntegerLiteral(IntVal, Context->IntTy, 
-                                           Exp->getLocStart());
-  InitExprs.push_back(len); // set "int numBytes".
-  
-  // struct NSConstantString
-  QualType CFConstantStrType = Context->getCFConstantStringType();
-  // (struct NSConstantString) { <exprs from above> }
-  InitListExpr *ILE = new InitListExpr(SourceLocation(), 
-                                       &InitExprs[0], InitExprs.size(), 
-                                       SourceLocation());
-  CompoundLiteralExpr *StrRep = new CompoundLiteralExpr(CFConstantStrType, ILE, false);
-  // struct NSConstantString *
-  expType = Context->getPointerType(StrRep->getType());
-  Unop = new UnaryOperator(StrRep, UnaryOperator::AddrOf, expType, 
-                           SourceLocation());
+  QualType strType = getConstantStringStructType();
+
+  std::string S = "__NSConstantStringImpl_";
+  S += utostr(NumObjCStringLiterals++);
+
+  std::string StrObjDecl = "static __NSConstantStringImpl " + S;
+  StrObjDecl += " = __NSConstantStringImpl(";
+  // The pretty printer for StringLiteral handles escape characters properly.
+  std::ostringstream prettyBuf;
+  Exp->getString()->printPretty(prettyBuf);
+  StrObjDecl += prettyBuf.str();
+  StrObjDecl += ",";
+  // FIXME: This length isn't correct. It doesn't include escape characters
+  // inserted by the pretty printer.
+  StrObjDecl += utostr(Exp->getString()->getByteLength()) + ");\n";
+  InsertText(SourceLocation::getFileLoc(MainFileID, 0), 
+             StrObjDecl.c_str(), StrObjDecl.size());
+  
+  FileVarDecl *NewVD = new FileVarDecl(SourceLocation(), 
+                                       &Context->Idents.get(S.c_str()), strType, 
+                                       VarDecl::Static, NULL);
+  DeclRefExpr *DRE = new DeclRefExpr(NewVD, strType, SourceLocation());
+  Expr *Unop = new UnaryOperator(DRE, UnaryOperator::AddrOf,
+                                 Context->getPointerType(DRE->getType()), 
+                                 SourceLocation());
   // cast to NSConstantString *
-  cast = new CastExpr(Exp->getType(), Unop, SourceLocation());
+  CastExpr *cast = new CastExpr(Exp->getType(), Unop, SourceLocation());
   ReplaceStmt(Exp, cast);
   delete Exp;
   return cast;
-#endif
 }
 
 ObjCInterfaceDecl *RewriteTest::isSuperReceiver(Expr *recExpr) {
@@ -1825,6 +1805,31 @@
   return Context->getTagDeclType(SuperStructDecl);
 }
 
+QualType RewriteTest::getConstantStringStructType() {
+  if (!ConstantStringDecl) {
+    ConstantStringDecl = new RecordDecl(Decl::Struct, SourceLocation(), 
+                                     &Context->Idents.get("__NSConstantStringImpl"), 0);
+    QualType FieldTypes[4];
+  
+    // struct objc_object *receiver;
+    FieldTypes[0] = Context->getObjCIdType();  
+    // int flags;
+    FieldTypes[1] = Context->IntTy;  
+    // char *str;
+    FieldTypes[2] = Context->getPointerType(Context->CharTy);  
+    // long length;
+    FieldTypes[3] = Context->LongTy;  
+    // Create fields
+    FieldDecl *FieldDecls[2];
+  
+    for (unsigned i = 0; i < 4; ++i)
+      FieldDecls[i] = new FieldDecl(SourceLocation(), 0, FieldTypes[i]);
+  
+    ConstantStringDecl->defineBody(FieldDecls, 4);
+  }
+  return Context->getTagDeclType(ConstantStringDecl);
+}
+
 Stmt *RewriteTest::SynthMessageExpr(ObjCMessageExpr *Exp) {
   if (!SelGetUidFunctionDecl)
     SynthSelGetUidFunctionDecl();





More information about the cfe-commits mailing list