]> granicus.if.org Git - clang/commitdiff
Add PCH support for ObjCMessageExpr (needed to build Mail).
authorSteve Naroff <snaroff@apple.com>
Sat, 25 Apr 2009 14:04:28 +0000 (14:04 +0000)
committerSteve Naroff <snaroff@apple.com>
Sat, 25 Apr 2009 14:04:28 +0000 (14:04 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70044 91177308-0d34-0410-b5e6-96231b3b80d8

include/clang/AST/ExprObjC.h
include/clang/Frontend/PCHBitCodes.h
lib/Frontend/PCHReader.cpp
lib/Frontend/PCHWriter.cpp

index 05f26d1ec08fc293b2ca0ff1ae0d227824a42849..d03956cf0b5a3794829f9b2a1b002a4765e65821 100644 (file)
@@ -357,6 +357,9 @@ public:
                   QualType retType, ObjCMethodDecl *methDecl,
                   SourceLocation LBrac, SourceLocation RBrac,
                   Expr **ArgExprs, unsigned NumArgs);
+                  
+  explicit ObjCMessageExpr(EmptyShell Empty)
+    : Expr(ObjCMessageExprClass, Empty) {}
   
   ~ObjCMessageExpr() {
     delete [] SubExprs;
@@ -373,12 +376,15 @@ public:
   const Expr *getReceiver() const {
     return const_cast<ObjCMessageExpr*>(this)->getReceiver();
   }
-  
+  // FIXME: need setters for different receiver types.
+  void setReceiver(Expr *rec) { SubExprs[RECEIVER] = rec; }
   Selector getSelector() const { return SelName; }
-
+  void setSelector(Selector S) { SelName = S; }
+  
   const ObjCMethodDecl *getMethodDecl() const { return MethodProto; }
   ObjCMethodDecl *getMethodDecl() { return MethodProto; }
-
+  void setMethodDecl(ObjCMethodDecl *MD) { MethodProto = MD; }
+  
   typedef std::pair<ObjCInterfaceDecl*, IdentifierInfo*> ClassInfo;
   
   /// getClassInfo - For class methods, this returns both the ObjCInterfaceDecl*
@@ -396,7 +402,8 @@ public:
   
   /// getNumArgs - Return the number of actual arguments to this call.
   unsigned getNumArgs() const { return NumArgs; }
-
+  void setNumArgs(unsigned nArgs) { NumArgs = nArgs; }
+  
   /// getArg - Return the specified argument.
   Expr *getArg(unsigned Arg) {
     assert(Arg < NumArgs && "Arg access out of range!");
@@ -412,6 +419,10 @@ public:
     SubExprs[Arg+ARGS_START] = ArgExpr;
   }
 
+  void setSourceRange(SourceRange R) {
+    LBracloc = R.getBegin();
+    RBracloc = R.getEnd();
+  }
   virtual SourceRange getSourceRange() const {
     return SourceRange(LBracloc, RBracloc);
   }
index b84d2edecfcca285c6783e05d8805c77341cf9c4..ba9d3e4c9d30716f53cae7138c87863b0aecafd4 100644 (file)
@@ -563,10 +563,12 @@ namespace clang {
       /// \brief A ObjCSelectorExpr record.
       EXPR_OBJC_SELECTOR_EXPR,
       /// \brief A ObjCProtocolExpr record.
-      EXPR_OBJC_PROTOCOL_EXPR
-
+      EXPR_OBJC_PROTOCOL_EXPR,
+      /// \brief A ObjCMessageExpr record.
+      EXPR_OBJC_MESSAGE_EXPR
+      
       // FIXME: From ExprObjC.h: ObjCIvarRefExpr, ObjCPropertyRefExpr,
-      // ObjCKVCRefExpr, ObjCMessageExpr, ObjCSuperExpr
+      // ObjCKVCRefExpr, ObjCSuperExpr
     };
 
     /// \brief The kinds of designators that can occur in a
index 300761a0e5d3ccd5863c30e3470658e71b98a23f..26b915800ae872565bc5d174efc0238db9703367 100644 (file)
@@ -497,6 +497,7 @@ namespace {
     unsigned VisitObjCEncodeExpr(ObjCEncodeExpr *E);
     unsigned VisitObjCSelectorExpr(ObjCSelectorExpr *E);
     unsigned VisitObjCProtocolExpr(ObjCProtocolExpr *E);
+    unsigned VisitObjCMessageExpr(ObjCMessageExpr *E);
   };
 }
 
@@ -1080,6 +1081,21 @@ unsigned PCHStmtReader::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
   return 0;
 }
 
+unsigned PCHStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) {
+  VisitExpr(E);
+  E->setNumArgs(Record[Idx++]);
+  SourceRange SR(SourceLocation::getFromRawEncoding(Record[Idx++]),
+                 SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setSourceRange(SR);
+  E->setSelector(Reader.GetSelector(Record, Idx));
+  E->setMethodDecl(cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
+  // FIXME: deal with class messages.
+  E->setReceiver(cast<Expr>(StmtStack[StmtStack.size() - E->getNumArgs() - 1]));
+  for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
+    E->setArg(I, cast<Expr>(StmtStack[StmtStack.size() - N + I]));
+  return E->getNumArgs() + 1;
+}
+
 
 //===----------------------------------------------------------------------===//
 // PCH reader implementation
@@ -3368,6 +3384,9 @@ Stmt *PCHReader::ReadStmt() {
     case pch::EXPR_OBJC_PROTOCOL_EXPR:
       S = new (Context) ObjCProtocolExpr(Empty);
       break;
+    case pch::EXPR_OBJC_MESSAGE_EXPR:
+      S = new (Context) ObjCMessageExpr(Empty);
+      break;
     }
 
     // We hit a STMT_STOP, so we're done with this expression.
index 5a410b1cf860063622e5ce635f62ddbc8beabf9a..f8c4a779fb715159135d02c0b7df90e5c703cd73 100644 (file)
@@ -672,6 +672,7 @@ namespace {
     void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
     void VisitObjCSelectorExpr(ObjCSelectorExpr *E);
     void VisitObjCProtocolExpr(ObjCProtocolExpr *E);
+    void VisitObjCMessageExpr(ObjCMessageExpr *E);
   };
 }
 
@@ -1198,6 +1199,21 @@ void PCHStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
   Code = pch::EXPR_OBJC_PROTOCOL_EXPR;
 }
 
+void PCHStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
+  VisitExpr(E);
+  Record.push_back(E->getNumArgs());
+  Writer.AddSourceLocation(E->getSourceRange().getBegin(), Record);
+  Writer.AddSourceLocation(E->getSourceRange().getEnd(), Record);
+  Writer.AddSelectorRef(E->getSelector(), Record);
+  Writer.AddDeclRef(E->getMethodDecl(), Record); // optional
+  // FIXME: deal with class messages.
+  Writer.WriteSubStmt(E->getReceiver());
+  for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
+       Arg != ArgEnd; ++Arg)
+    Writer.WriteSubStmt(*Arg);
+  Code = pch::EXPR_OBJC_MESSAGE_EXPR;
+}
+
 
 //===----------------------------------------------------------------------===//
 // PCHWriter Implementation