[cfe-commits] r43665 - in /cfe/trunk: AST/ASTContext.cpp Driver/RewriteTest.cpp Parse/ParseObjc.cpp Sema/Sema.h Sema/SemaExpr.cpp include/clang/AST/ASTContext.h include/clang/AST/Expr.h include/clang/Parse/Action.h include/clang/Parse/Parser.h

Steve Naroff snaroff at apple.com
Sat Nov 3 04:27:20 PDT 2007


Author: snaroff
Date: Sat Nov  3 06:27:19 2007
New Revision: 43665

URL: http://llvm.org/viewvc/llvm-project?rev=43665&view=rev
Log:

Implement rewrite rules for ObjC string constants.


Modified:
    cfe/trunk/AST/ASTContext.cpp
    cfe/trunk/Driver/RewriteTest.cpp
    cfe/trunk/Parse/ParseObjc.cpp
    cfe/trunk/Sema/Sema.h
    cfe/trunk/Sema/SemaExpr.cpp
    cfe/trunk/include/clang/AST/ASTContext.h
    cfe/trunk/include/clang/AST/Expr.h
    cfe/trunk/include/clang/Parse/Action.h
    cfe/trunk/include/clang/Parse/Parser.h

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

==============================================================================
--- cfe/trunk/AST/ASTContext.cpp (original)
+++ cfe/trunk/AST/ASTContext.cpp Sat Nov  3 06:27:19 2007
@@ -861,23 +861,20 @@
 QualType ASTContext::getCFConstantStringType() {
   if (!CFConstantStringTypeDecl) {
     CFConstantStringTypeDecl = new RecordDecl(Decl::Struct, SourceLocation(), 
-                                              &Idents.get("__builtin_CFString"), 
+                                              &Idents.get("NSConstantString"),
                                               0);
-  
-    QualType FieldTypes[4];
+    QualType FieldTypes[3];
   
     // const int *isa;
     FieldTypes[0] = getPointerType(IntTy.getQualifiedType(QualType::Const));  
-    // int flags;
-    FieldTypes[1] = IntTy;  
     // const char *str;
-    FieldTypes[2] = getPointerType(CharTy.getQualifiedType(QualType::Const));  
+    FieldTypes[1] = getPointerType(CharTy.getQualifiedType(QualType::Const));  
     // long length;
-    FieldTypes[3] = LongTy;  
+    FieldTypes[2] = LongTy;  
     // Create fields
-    FieldDecl *FieldDecls[4];
+    FieldDecl *FieldDecls[3];
   
-    for (unsigned i = 0; i < 4; ++i)
+    for (unsigned i = 0; i < 3; ++i)
       FieldDecls[i] = new FieldDecl(SourceLocation(), 0, FieldTypes[i]);
   
     CFConstantStringTypeDecl->defineBody(FieldDecls, 4);

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

==============================================================================
--- cfe/trunk/Driver/RewriteTest.cpp (original)
+++ cfe/trunk/Driver/RewriteTest.cpp Sat Nov  3 06:27:19 2007
@@ -39,6 +39,10 @@
     FunctionDecl *GetClassFunctionDecl;
     FunctionDecl *SelGetUidFunctionDecl;
     
+    // ObjC string constant support.
+    FileVarDecl *ConstantStringClassReference;
+    RecordDecl *NSStringRecord;
+      
     static const int OBJC_ABI_VERSION =7 ;
   public:
     void Initialize(ASTContext &context, unsigned mainFileID) {
@@ -48,6 +52,8 @@
       MsgSendFunctionDecl = 0;
       GetClassFunctionDecl = 0;
       SelGetUidFunctionDecl = 0;
+      ConstantStringClassReference = 0;
+      NSStringRecord = 0;
       Rewrite.setSourceMgr(Context->SourceMgr);
     }
 
@@ -73,12 +79,14 @@
     Stmt *RewriteFunctionBody(Stmt *S);
     Stmt *RewriteAtEncode(ObjCEncodeExpr *Exp);
     Stmt *RewriteMessageExpr(ObjCMessageExpr *Exp);
+    Stmt *RewriteObjCStringLiteral(ObjCStringLiteral *Exp);
     CallExpr *SynthesizeCallToFunctionDecl(FunctionDecl *FD, 
                                            Expr **args, unsigned nargs);
     void SynthMsgSendFunctionDecl();
     void SynthGetClassFunctionDecl();
     
     // Metadata emission.
+    void HandleObjcMetaDataEmission();
     void RewriteObjcClassMetaData(ObjcImplementationDecl *IDecl,
                                   std::string &Result);
     
@@ -125,6 +133,12 @@
   // Look for built-in declarations that we need to refer during the rewrite.
   if (FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
     RewriteFunctionDecl(FD);
+  } else if (FileVarDecl *FVD = dyn_cast<FileVarDecl>(D)) {
+    // declared in <Foundation/NSString.h>
+    if (strcmp(FVD->getName(), "_NSConstantStringClassReference") == 0) {
+      ConstantStringClassReference = FVD;
+      return;
+    }
   } else if (ObjcInterfaceDecl *MD = dyn_cast<ObjcInterfaceDecl>(D)) {
     RewriteInterfaceDecl(MD);
   } else if (ObjcCategoryDecl *CD = dyn_cast<ObjcCategoryDecl>(D)) {
@@ -161,17 +175,11 @@
   // Get the top-level buffer that this corresponds to.
   RewriteTabs();
   
-  // Rewrite Objective-c meta data*
-  std::string ResultStr;
-  WriteObjcMetaData(ResultStr);
-  // For now just print the string out.
-  printf("%s", ResultStr.c_str());
-  
   // Get the buffer corresponding to MainFileID.  If we haven't changed it, then
   // we are done.
   if (const RewriteBuffer *RewriteBuf = 
       Rewrite.getRewriteBufferFor(MainFileID)) {
-    printf("Changed:\n");
+    //printf("Changed:\n");
     std::string S(RewriteBuf->begin(), RewriteBuf->end());
     printf("%s\n", S.c_str());
   } else {
@@ -180,6 +188,16 @@
 
 }
 
+/// HandleObjcMetaDataEmission - main routine to generate objective-c's 
+/// metadata.
+void RewriteTest::HandleObjcMetaDataEmission() {
+  // Rewrite Objective-c meta data*
+  std::string ResultStr;
+  WriteObjcMetaData(ResultStr);
+  // For now just print the string out.
+  printf("%s", ResultStr.c_str());
+}
+
 //===----------------------------------------------------------------------===//
 // Syntactic (non-AST) Rewriting Code
 //===----------------------------------------------------------------------===//
@@ -364,6 +382,9 @@
   // Handle specific things.
   if (ObjCEncodeExpr *AtEncode = dyn_cast<ObjCEncodeExpr>(S))
     return RewriteAtEncode(AtEncode);
+	
+  if (ObjCStringLiteral *AtString = dyn_cast<ObjCStringLiteral>(S))
+    return RewriteObjCStringLiteral(AtString);
     
   if (ObjCMessageExpr *MessExpr = dyn_cast<ObjCMessageExpr>(S)) {
     // Before we rewrite it, put the original message expression in a comment.
@@ -492,7 +513,7 @@
 
 void RewriteTest::RewriteFunctionDecl(FunctionDecl *FD) {
   // declared in <objc/objc.h>
-  if (strcmp(FD->getName(), "sel_getUid") == 0) {
+  if (strcmp(FD->getName(), "sel_registerName") == 0) {
     SelGetUidFunctionDecl = FD;
     return;
   }
@@ -536,8 +557,52 @@
                                           FunctionDecl::Extern, false, 0);
 }
 
+Stmt *RewriteTest::RewriteObjCStringLiteral(ObjCStringLiteral *Exp) {
+  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);
+  // struct NSConstantString *
+  expType = Context->getPointerType(StrRep->getType());
+  Unop = new UnaryOperator(StrRep, UnaryOperator::AddrOf, expType, 
+                           SourceLocation());
+  // struct NSString *
+  if (!NSStringRecord)
+    NSStringRecord = new RecordDecl(Decl::Struct, SourceLocation(), 
+                                    &Context->Idents.get("NSString"), 0);
+  expType = Context->getPointerType(Context->getTagDeclType(NSStringRecord));
+  cast = new CastExpr(expType, Unop, SourceLocation());
+  Rewrite.ReplaceStmt(Exp, cast);
+  delete Exp;
+  return StrRep;
+}
+
 Stmt *RewriteTest::RewriteMessageExpr(ObjCMessageExpr *Exp) {
-  assert(SelGetUidFunctionDecl && "Can't find sel_getUid() decl");
+  assert(SelGetUidFunctionDecl && "Can't find sel_registerName() decl");
   if (!MsgSendFunctionDecl)
     SynthMsgSendFunctionDecl();
   if (!GetClassFunctionDecl)
@@ -561,7 +626,7 @@
   } else // instance message.
     MsgExprs.push_back(Exp->getReceiver());
     
-  // Create a call to sel_getUid("selName"), it will be the 2nd argument.
+  // Create a call to sel_registerName("selName"), it will be the 2nd argument.
   llvm::SmallVector<Expr*, 8> SelExprs;
   QualType argType = Context->getPointerType(Context->CharTy);
   SelExprs.push_back(new StringLiteral(Exp->getSelector().getName().c_str(),

Modified: cfe/trunk/Parse/ParseObjc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Parse/ParseObjc.cpp?rev=43665&r1=43664&r2=43665&view=diff

==============================================================================
--- cfe/trunk/Parse/ParseObjc.cpp (original)
+++ cfe/trunk/Parse/ParseObjc.cpp Sat Nov  3 06:27:19 2007
@@ -1155,7 +1155,7 @@
   switch (Tok.getKind()) {
     case tok::string_literal:    // primary-expression: string-literal
     case tok::wide_string_literal:
-      return ParsePostfixExpressionSuffix(ParseObjCStringLiteral());
+      return ParsePostfixExpressionSuffix(ParseObjCStringLiteral(AtLoc));
     default:
       break;
   }
@@ -1285,12 +1285,12 @@
                                       &KeyExprs[0]);
 }
 
-Parser::ExprResult Parser::ParseObjCStringLiteral() {
+Parser::ExprResult Parser::ParseObjCStringLiteral(SourceLocation AtLoc) {
   ExprResult Res = ParseStringLiteralExpression();
 
   if (Res.isInvalid) return Res;
 
-  return Actions.ParseObjCStringLiteral(Res.Val);
+  return Actions.ParseObjCStringLiteral(AtLoc, Res.Val);
 }
 
 ///    objc-encode-expression:

Modified: cfe/trunk/Sema/Sema.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/Sema.h?rev=43665&r1=43664&r2=43665&view=diff

==============================================================================
--- cfe/trunk/Sema/Sema.h (original)
+++ cfe/trunk/Sema/Sema.h Sat Nov  3 06:27:19 2007
@@ -454,7 +454,8 @@
                                          tok::TokenKind Kind);
   
   // ParseObjCStringLiteral - Parse Objective-C string literals.
-  virtual ExprResult ParseObjCStringLiteral(ExprTy *string);
+  virtual ExprResult ParseObjCStringLiteral(SourceLocation AtLoc,
+                                            ExprTy *string);
   virtual ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc,
                                                SourceLocation EncodeLoc,
                                                SourceLocation LParenLoc,

Modified: cfe/trunk/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Sema/SemaExpr.cpp?rev=43665&r1=43664&r2=43665&view=diff

==============================================================================
--- cfe/trunk/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/Sema/SemaExpr.cpp Sat Nov  3 06:27:19 2007
@@ -1929,7 +1929,8 @@
 }
 
 // TODO: Move this to SemaObjC.cpp
-Sema::ExprResult Sema::ParseObjCStringLiteral(ExprTy *string) {
+Sema::ExprResult Sema::ParseObjCStringLiteral(SourceLocation AtLoc, 
+                                              ExprTy *string) {
   StringLiteral* S = static_cast<StringLiteral *>(string);
   
   if (CheckBuiltinCFStringArgument(S))
@@ -1949,7 +1950,7 @@
   }
   QualType t = Context.getObjcConstantStringInterface();
   t = Context.getPointerType(t);
-  return new ObjCStringLiteral(S, t);
+  return new ObjCStringLiteral(S, t, AtLoc);
 }
 
 Sema::ExprResult Sema::ParseObjCEncodeExpression(SourceLocation AtLoc,

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

==============================================================================
--- cfe/trunk/include/clang/AST/ASTContext.h (original)
+++ cfe/trunk/include/clang/AST/ASTContext.h Sat Nov  3 06:27:19 2007
@@ -178,8 +178,8 @@
   /// defined in <stddef.h>. Pointer - pointer requires this (C99 6.5.6p9).
   QualType getPointerDiffType() const;
   
-  // getCFConstantStringType - Return the type used for constant CFStrings.
-  // CURRENTLY UNUSED (10/15/07). ObjCStringLiteral now uses the hook below.
+  // getCFConstantStringType - Return the C structure type used to represent
+  // constant CFStrings.
   QualType getCFConstantStringType(); 
   
   // This setter/getter represents the ObjC type for an NSConstantString.

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

==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Sat Nov  3 06:27:19 2007
@@ -1062,16 +1062,17 @@
 /// i.e. @"foo".
 class ObjCStringLiteral : public Expr {
   StringLiteral *String;
+  SourceLocation AtLoc;
 public:
-  ObjCStringLiteral(StringLiteral *SL, QualType T)
-    : Expr(ObjCStringLiteralClass, T), String(SL) {}
+  ObjCStringLiteral(StringLiteral *SL, QualType T, SourceLocation L)
+    : Expr(ObjCStringLiteralClass, T), String(SL), AtLoc(L) {}
   
   StringLiteral* getString() { return String; }
 
   const StringLiteral* getString() const { return String; }
 
   virtual SourceRange getSourceRange() const { 
-    return String->getSourceRange();
+    return SourceRange(AtLoc, String->getLocEnd());
   }
   
   static bool classof(const Stmt *T) { 

Modified: cfe/trunk/include/clang/Parse/Action.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Action.h?rev=43665&r1=43664&r2=43665&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Action.h (original)
+++ cfe/trunk/include/clang/Parse/Action.h Sat Nov  3 06:27:19 2007
@@ -612,7 +612,8 @@
                                                
                                                
   //===----------------------- Obj-C Expressions --------------------------===//
-  virtual ExprResult ParseObjCStringLiteral(ExprTy *string) {
+  virtual ExprResult ParseObjCStringLiteral(SourceLocation AtLoc, 
+                                            ExprTy *string) {
     return 0;
   }
 

Modified: cfe/trunk/include/clang/Parse/Parser.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Parse/Parser.h?rev=43665&r1=43664&r2=43665&view=diff

==============================================================================
--- cfe/trunk/include/clang/Parse/Parser.h (original)
+++ cfe/trunk/include/clang/Parse/Parser.h Sat Nov  3 06:27:19 2007
@@ -362,7 +362,7 @@
   //===--------------------------------------------------------------------===//
   // Objective-C Expressions
   ExprResult ParseObjCAtExpression(SourceLocation AtLocation);
-  ExprResult ParseObjCStringLiteral();
+  ExprResult ParseObjCStringLiteral(SourceLocation AtLoc);
   ExprResult ParseObjCEncodeExpression(SourceLocation AtLoc);
   ExprResult ParseObjCSelectorExpression(SourceLocation AtLoc);
   ExprResult ParseObjCProtocolExpression(SourceLocation AtLoc);





More information about the cfe-commits mailing list