]> granicus.if.org Git - clang/commitdiff
implement PCH support for the rest of ExprObjC.h, including
authorChris Lattner <sabre@nondot.org>
Sun, 26 Apr 2009 00:44:05 +0000 (00:44 +0000)
committerChris Lattner <sabre@nondot.org>
Sun, 26 Apr 2009 00:44:05 +0000 (00:44 +0000)
the missing bits of ObjCMessageExpr.

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70100 91177308-0d34-0410-b5e6-96231b3b80d8

clang.xcodeproj/project.pbxproj
include/clang/AST/ExprObjC.h
include/clang/Frontend/PCHBitCodes.h
lib/AST/Expr.cpp
lib/Frontend/PCHReader.cpp
lib/Frontend/PCHWriter.cpp

index 6bacb1d98b3b502389a15cd3341dbdf39cf6f10f..a92bcca1c401fb8d5cb85adb0702895d6d2031e9 100644 (file)
                DED7D9E50A5257F6003AD0FB /* ScratchBuffer.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DED7D9E40A5257F6003AD0FB /* ScratchBuffer.cpp */; };
                DEDFE5CF0F7206E40035BD10 /* NestedNameSpecifier.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE5CE0F7206E40035BD10 /* NestedNameSpecifier.cpp */; };
                DEDFE6350F7B3B180035BD10 /* Warnings.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE6220F7B3B180035BD10 /* Warnings.cpp */; };
-               DEDFE6360F7B3B180035BD10 /* SerializationTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE6230F7B3B180035BD10 /* SerializationTest.cpp */; };
                DEDFE6370F7B3B180035BD10 /* RewriteTest.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE6240F7B3B180035BD10 /* RewriteTest.cpp */; };
                DEDFE6380F7B3B180035BD10 /* DependencyFile.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE6250F7B3B180035BD10 /* DependencyFile.cpp */; };
                DEDFE6390F7B3B180035BD10 /* HTMLPrint.cpp in Sources */ = {isa = PBXBuildFile; fileRef = DEDFE6260F7B3B180035BD10 /* HTMLPrint.cpp */; };
                DEDFE5CB0F7206CC0035BD10 /* NestedNameSpecifier.h */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.c.h; name = NestedNameSpecifier.h; path = clang/AST/NestedNameSpecifier.h; sourceTree = "<group>"; };
                DEDFE5CE0F7206E40035BD10 /* NestedNameSpecifier.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = NestedNameSpecifier.cpp; path = lib/AST/NestedNameSpecifier.cpp; sourceTree = "<group>"; };
                DEDFE6220F7B3B180035BD10 /* Warnings.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Warnings.cpp; path = "tools/clang-cc/Warnings.cpp"; sourceTree = "<group>"; tabWidth = 2; };
-               DEDFE6230F7B3B180035BD10 /* SerializationTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = SerializationTest.cpp; path = "tools/clang-cc/SerializationTest.cpp"; sourceTree = "<group>"; tabWidth = 2; };
                DEDFE6240F7B3B180035BD10 /* RewriteTest.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = RewriteTest.cpp; path = "tools/clang-cc/RewriteTest.cpp"; sourceTree = "<group>"; tabWidth = 2; };
                DEDFE6250F7B3B180035BD10 /* DependencyFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = DependencyFile.cpp; path = "tools/clang-cc/DependencyFile.cpp"; sourceTree = "<group>"; tabWidth = 2; };
                DEDFE6260F7B3B180035BD10 /* HTMLPrint.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = HTMLPrint.cpp; path = "tools/clang-cc/HTMLPrint.cpp"; sourceTree = "<group>"; tabWidth = 2; };
                                DEDFE6310F7B3B180035BD10 /* RewriteMacros.cpp */,
                                DEDFE62F0F7B3B180035BD10 /* RewriteObjC.cpp */,
                                DEDFE6240F7B3B180035BD10 /* RewriteTest.cpp */,
-                               DEDFE6230F7B3B180035BD10 /* SerializationTest.cpp */,
                                DEDFE6220F7B3B180035BD10 /* Warnings.cpp */,
                                1AFEF4050F8A6B2300476F2B /* clang-cc.cpp */,
                                1AFEF4060F8A6B2300476F2B /* clang-cc.h */,
                                DEDFE5CF0F7206E40035BD10 /* NestedNameSpecifier.cpp in Sources */,
                                1ADF47AF0F782C3200E48A8A /* SemaTemplateInstantiateDecl.cpp in Sources */,
                                DEDFE6350F7B3B180035BD10 /* Warnings.cpp in Sources */,
-                               DEDFE6360F7B3B180035BD10 /* SerializationTest.cpp in Sources */,
                                DEDFE6370F7B3B180035BD10 /* RewriteTest.cpp in Sources */,
                                DEDFE6380F7B3B180035BD10 /* DependencyFile.cpp in Sources */,
                                DEDFE6390F7B3B180035BD10 /* HTMLPrint.cpp in Sources */,
index d03956cf0b5a3794829f9b2a1b002a4765e65821..8ab7f49d4f033df6e53f4b8ab76a7e91f3ae2163 100644 (file)
@@ -181,19 +181,29 @@ public:
     Loc(l), Base(base), IsArrow(arrow),
     IsFreeIvar(freeIvar) {}
   
+  explicit ObjCIvarRefExpr(EmptyShell Empty)
+    : Expr(ObjCIvarRefExprClass, Empty) {}
+
   ObjCIvarDecl *getDecl() { return D; }
   const ObjCIvarDecl *getDecl() const { return D; }
-  virtual SourceRange getSourceRange() const { 
-    return isFreeIvar() ? SourceRange(Loc)
-                        : SourceRange(getBase()->getLocStart(), Loc); 
-  }
+  void setDecl(ObjCIvarDecl *d) { D = d; }
+  
   const Expr *getBase() const { return cast<Expr>(Base); }
   Expr *getBase() { return cast<Expr>(Base); }
   void setBase(Expr * base) { Base = base; }
+  
   bool isArrow() const { return IsArrow; }
   bool isFreeIvar() const { return IsFreeIvar; }
+  void setIsArrow(bool A) { IsArrow = A; }
+  void setIsFreeIvar(bool A) { IsFreeIvar = A; }
   
   SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+
+  virtual SourceRange getSourceRange() const { 
+    return isFreeIvar() ? SourceRange(Loc)
+    : SourceRange(getBase()->getLocStart(), Loc); 
+  }
   
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == ObjCIvarRefExprClass; 
@@ -218,19 +228,24 @@ public:
                       SourceLocation l, Expr *base)
     : Expr(ObjCPropertyRefExprClass, t), AsProperty(PD), IdLoc(l), Base(base) {
   }
-  ObjCPropertyDecl *getProperty() const {
-    return AsProperty;
-  }
   
-  virtual SourceRange getSourceRange() const {
-    return SourceRange(getBase()->getLocStart(), IdLoc);
-  }
+  explicit ObjCPropertyRefExpr(EmptyShell Empty)
+    : Expr(ObjCPropertyRefExprClass, Empty) {}
+
+  ObjCPropertyDecl *getProperty() const { return AsProperty; }
+  void setProperty(ObjCPropertyDecl *D) { AsProperty = D; }
+  
   const Expr *getBase() const { return cast<Expr>(Base); }
   Expr *getBase() { return cast<Expr>(Base); }
-  void setBase(Expr * base) { Base = base; }
+  void setBase(Expr *base) { Base = base; }
   
   SourceLocation getLocation() const { return IdLoc; }
+  void setLocation(SourceLocation L) { IdLoc = L; }
 
+  virtual SourceRange getSourceRange() const {
+    return SourceRange(getBase()->getLocStart(), IdLoc);
+  }
+  
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == ObjCPropertyRefExprClass; 
   }
@@ -261,7 +276,8 @@ public:
                  ObjCMethodDecl *setter,
                  SourceLocation l, Expr *base)
     : Expr(ObjCKVCRefExprClass, t), Setter(setter),
-      Getter(getter), Loc(l), Base(base), ClassProp(0), ClassLoc(SourceLocation()) {
+      Getter(getter), Loc(l), Base(base), ClassProp(0),
+      ClassLoc(SourceLocation()) {
     }
   ObjCKVCRefExpr(ObjCMethodDecl *getter,
                  QualType t, 
@@ -270,17 +286,14 @@ public:
     : Expr(ObjCKVCRefExprClass, t), Setter(setter),
       Getter(getter), Loc(l), Base(0), ClassProp(C), ClassLoc(CL) {
     }
-  
-  ObjCMethodDecl *getGetterMethod() const {
-      return Getter;
-  }
-  ObjCMethodDecl *getSetterMethod() const {
-    return Setter;
-  }
+  explicit ObjCKVCRefExpr(EmptyShell Empty) : Expr(ObjCKVCRefExprClass, Empty){}
 
-  ObjCInterfaceDecl *getClassProp() const {
-    return ClassProp;
-  }
+  ObjCMethodDecl *getGetterMethod() const { return Getter; }
+  ObjCMethodDecl *getSetterMethod() const { return Setter; }
+  ObjCInterfaceDecl *getClassProp() const { return ClassProp; }
+  void setGetterMethod(ObjCMethodDecl *D) { Getter = D; }
+  void setSetterMethod(ObjCMethodDecl *D) { Setter = D; }
+  void setClassProp(ObjCInterfaceDecl *D) { ClassProp = D; }
   
   virtual SourceRange getSourceRange() const {
     if (Base)
@@ -289,9 +302,12 @@ public:
   }
   const Expr *getBase() const { return cast<Expr>(Base); }
   Expr *getBase() { return cast<Expr>(Base); }
-  void setBase(Expr * base) { Base = base; }
+  void setBase(Expr *base) { Base = base; }
     
   SourceLocation getLocation() const { return Loc; }
+  void setLocation(SourceLocation L) { Loc = L; }
+  SourceLocation getClassLoc() const { return ClassLoc; }
+  void setClassLoc(SourceLocation L) { ClassLoc = L; }
     
   static bool classof(const Stmt *T) { 
     return T->getStmtClass() == ObjCKVCRefExprClass; 
@@ -324,7 +340,7 @@ class ObjCMessageExpr : public Expr {
   // Constants for indexing into SubExprs.
   enum { RECEIVER=0, ARGS_START=1 };
 
-  // Bit-swizziling flags.
+  // Bit-swizzling flags.
   enum { IsInstMeth=0, IsClsMethDeclUnknown, IsClsMethDeclKnown, Flags=0x3 };
   unsigned getFlag() const { return (uintptr_t) SubExprs[RECEIVER] & Flags; }
   
@@ -391,14 +407,14 @@ public:
   ///  and IdentifierInfo* of the invoked class.  Both can be NULL if this
   ///  is an instance message, and the ObjCInterfaceDecl* can be NULL if none
   ///  was available when this ObjCMessageExpr object was constructed.  
-  ClassInfo getClassInfo() const;  
+  ClassInfo getClassInfo() const; 
+  void setClassInfo(const ClassInfo &C);
   
   /// getClassName - For class methods, this returns the invoked class,
   ///  and returns NULL otherwise.  For instance methods, use getReceiver.  
   IdentifierInfo *getClassName() const {
     return getClassInfo().second;
   }
-
   
   /// getNumArgs - Return the number of actual arguments to this call.
   unsigned getNumArgs() const { return NumArgs; }
@@ -418,7 +434,13 @@ public:
     assert(Arg < NumArgs && "Arg access out of range!");
     SubExprs[Arg+ARGS_START] = ArgExpr;
   }
+  
+  SourceLocation getLeftLoc() const { return LBracloc; }
+  SourceLocation getRightLoc() const { return RBracloc; }
 
+  void setLeftLoc(SourceLocation L) { LBracloc = L; }
+  void setRightLoc(SourceLocation L) { RBracloc = L; }
+  
   void setSourceRange(SourceRange R) {
     LBracloc = R.getBegin();
     RBracloc = R.getEnd();
@@ -452,7 +474,11 @@ class ObjCSuperExpr : public Expr {
 public:
   ObjCSuperExpr(SourceLocation L, QualType Type) 
     : Expr(ObjCSuperExprClass, Type), Loc(L) { }
+  explicit ObjCSuperExpr(EmptyShell Empty) : Expr(ObjCSuperExprClass, Empty) {}
 
+  SourceLocation getLoc() const { return Loc; }
+  void setLoc(SourceLocation L) { Loc = L; }
+  
   virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
 
   static bool classof(const Stmt *T) { 
index f486920316269875f20f6e6fe508652733b6cc62..c57752b9976b0859a51afd7bc509b81e389c75d6 100644 (file)
@@ -553,19 +553,24 @@ namespace clang {
       
       // Objective-C
       
-      /// \brief A ObjCStringLiteral record.
+      /// \brief An ObjCStringLiteral record.
       EXPR_OBJC_STRING_LITERAL,
-      /// \brief A ObjCEncodeExpr record.
+      /// \brief An ObjCEncodeExpr record.
       EXPR_OBJC_ENCODE,
-      /// \brief A ObjCSelectorExpr record.
+      /// \brief An ObjCSelectorExpr record.
       EXPR_OBJC_SELECTOR_EXPR,
-      /// \brief A ObjCProtocolExpr record.
+      /// \brief An ObjCProtocolExpr record.
       EXPR_OBJC_PROTOCOL_EXPR,
-      /// \brief A ObjCMessageExpr record.
-      EXPR_OBJC_MESSAGE_EXPR
-      
-      // FIXME: From ExprObjC.h: ObjCIvarRefExpr, ObjCPropertyRefExpr,
-      // ObjCKVCRefExpr, ObjCSuperExpr
+      /// \brief An ObjCIvarRefExpr record.
+      EXPR_OBJC_IVAR_REF_EXPR,
+      /// \brief An ObjCPropertyRefExpr record.
+      EXPR_OBJC_PROPERTY_REF_EXPR,
+      /// \brief An ObjCKVCRefExpr record.
+      EXPR_OBJC_KVC_REF_EXPR,
+      /// \brief An ObjCMessageExpr record.
+      EXPR_OBJC_MESSAGE_EXPR,
+      /// \brief An ObjCSuperExpr record.
+      EXPR_OBJC_SUPER_EXPR
     };
 
     /// \brief The kinds of designators that can occur in a
index f9ca323a4747059a2ab7c2f0acffc50967124785..053117d35bec796d3e25f52bc33bd6e9d42d61c6 100644 (file)
@@ -1525,6 +1525,16 @@ ObjCMessageExpr::ClassInfo ObjCMessageExpr::getClassInfo() const {
   }
 }
 
+void ObjCMessageExpr::setClassInfo(const ObjCMessageExpr::ClassInfo &CI) {
+  if (CI.first == 0 && CI.second == 0)
+    SubExprs[RECEIVER] = (Expr*)((uintptr_t)0 | IsInstMeth);
+  else if (CI.first == 0)
+    SubExprs[RECEIVER] = (Expr*)((uintptr_t)CI.second | IsClsMethDeclUnknown);
+  else
+    SubExprs[RECEIVER] = (Expr*)((uintptr_t)CI.first | IsClsMethDeclKnown);
+}
+
+
 bool ChooseExpr::isConditionTrue(ASTContext &C) const {
   return getCond()->getIntegerConstantExprValue(C) != 0;
 }
index d824c5684833908dd6d4b20df70205761cc7c299..9970eb2b0905617ab9f6da0bccc1bbcbb006671f 100644 (file)
@@ -497,7 +497,11 @@ namespace {
     unsigned VisitObjCEncodeExpr(ObjCEncodeExpr *E);
     unsigned VisitObjCSelectorExpr(ObjCSelectorExpr *E);
     unsigned VisitObjCProtocolExpr(ObjCProtocolExpr *E);
+    unsigned VisitObjCIvarRefExpr(ObjCIvarRefExpr *E);
+    unsigned VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
+    unsigned VisitObjCKVCRefExpr(ObjCKVCRefExpr *E);
     unsigned VisitObjCMessageExpr(ObjCMessageExpr *E);
+    unsigned VisitObjCSuperExpr(ObjCSuperExpr *E);
   };
 }
 
@@ -1081,21 +1085,60 @@ unsigned PCHStmtReader::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
   return 0;
 }
 
+unsigned PCHStmtReader::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+  VisitExpr(E);
+  E->setDecl(cast<ObjCIvarDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setBase(cast<Expr>(StmtStack.back()));
+  E->setIsArrow(Record[Idx++]);
+  E->setIsFreeIvar(Record[Idx++]);
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+  VisitExpr(E);
+  E->setProperty(cast<ObjCPropertyDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setBase(cast<Expr>(StmtStack.back()));
+  return 1;
+}
+
+unsigned PCHStmtReader::VisitObjCKVCRefExpr(ObjCKVCRefExpr *E) {
+  VisitExpr(E);
+  E->setGetterMethod(cast<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setSetterMethod(cast<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setClassProp(cast<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++])));
+  E->setBase(cast<Expr>(StmtStack.back()));
+  E->setLocation(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setClassLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 1;
+}
+
 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->setLeftLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRightLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
   E->setSelector(Reader.GetSelector(Record, Idx));
   E->setMethodDecl(cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
-  // FIXME: deal with class messages.
+  
+  ObjCMessageExpr::ClassInfo CI;
+  CI.first = cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++]));
+  CI.second = Reader.GetIdentifierInfo(Record, Idx);
+  if (E->getMethodDecl() == 0)
+    E->setClassInfo(CI);
+  
   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;
 }
 
+unsigned PCHStmtReader::VisitObjCSuperExpr(ObjCSuperExpr *E) {
+  VisitExpr(E);
+  E->setLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  return 0;
+}
 
 //===----------------------------------------------------------------------===//
 // PCH reader implementation
@@ -3312,9 +3355,21 @@ Stmt *PCHReader::ReadStmt() {
     case pch::EXPR_OBJC_PROTOCOL_EXPR:
       S = new (Context) ObjCProtocolExpr(Empty);
       break;
+    case pch::EXPR_OBJC_IVAR_REF_EXPR:
+      S = new (Context) ObjCIvarRefExpr(Empty);
+      break;
+    case pch::EXPR_OBJC_PROPERTY_REF_EXPR:
+      S = new (Context) ObjCPropertyRefExpr(Empty);
+      break;
+    case pch::EXPR_OBJC_KVC_REF_EXPR:
+      S = new (Context) ObjCKVCRefExpr(Empty);
+      break;
     case pch::EXPR_OBJC_MESSAGE_EXPR:
       S = new (Context) ObjCMessageExpr(Empty);
       break;
+    case pch::EXPR_OBJC_SUPER_EXPR:
+      S = new (Context) ObjCSuperExpr(Empty);
+      break;
     }
 
     // We hit a STMT_STOP, so we're done with this expression.
index 59aabfe0e4f20e04ac32ceb610001c591b3d8dd6..f648a75650d62a8560cab2a914ac1767b699dd7e 100644 (file)
@@ -672,7 +672,11 @@ namespace {
     void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
     void VisitObjCSelectorExpr(ObjCSelectorExpr *E);
     void VisitObjCProtocolExpr(ObjCProtocolExpr *E);
+    void VisitObjCIvarRefExpr(ObjCIvarRefExpr *E);
+    void VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E);
+    void VisitObjCKVCRefExpr(ObjCKVCRefExpr *E);
     void VisitObjCMessageExpr(ObjCMessageExpr *E);
+    void VisitObjCSuperExpr(ObjCSuperExpr *E);
   };
 }
 
@@ -1199,21 +1203,59 @@ void PCHStmtWriter::VisitObjCProtocolExpr(ObjCProtocolExpr *E) {
   Code = pch::EXPR_OBJC_PROTOCOL_EXPR;
 }
 
+void PCHStmtWriter::VisitObjCIvarRefExpr(ObjCIvarRefExpr *E) {
+  VisitExpr(E);
+  Writer.AddDeclRef(E->getDecl(), Record);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Writer.WriteSubStmt(E->getBase());
+  Record.push_back(E->isArrow());
+  Record.push_back(E->isFreeIvar());
+}
+
+void PCHStmtWriter::VisitObjCPropertyRefExpr(ObjCPropertyRefExpr *E) {
+  VisitExpr(E);
+  Writer.AddDeclRef(E->getProperty(), Record);
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Writer.WriteSubStmt(E->getBase());
+}
+
+void PCHStmtWriter::VisitObjCKVCRefExpr(ObjCKVCRefExpr *E) {
+  VisitExpr(E);
+  Writer.AddDeclRef(E->getGetterMethod(), Record);
+  Writer.AddDeclRef(E->getSetterMethod(), Record);
+  
+  // NOTE: ClassProp and Base are mutually exclusive.
+  Writer.AddDeclRef(E->getClassProp(), Record);
+  Writer.WriteSubStmt(E->getBase());
+  Writer.AddSourceLocation(E->getLocation(), Record);
+  Writer.AddSourceLocation(E->getClassLoc(), Record);
+}
+
 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.AddSourceLocation(E->getLeftLoc(), Record);
+  Writer.AddSourceLocation(E->getRightLoc(), Record);
   Writer.AddSelectorRef(E->getSelector(), Record);
   Writer.AddDeclRef(E->getMethodDecl(), Record); // optional
-  // FIXME: deal with class messages.
+
+  ObjCMessageExpr::ClassInfo CI = E->getClassInfo();
   Writer.WriteSubStmt(E->getReceiver());
+  Writer.AddDeclRef(CI.first, Record);
+  Writer.AddIdentifierRef(CI.second, Record);
+  
   for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
        Arg != ArgEnd; ++Arg)
     Writer.WriteSubStmt(*Arg);
   Code = pch::EXPR_OBJC_MESSAGE_EXPR;
 }
 
+void PCHStmtWriter::VisitObjCSuperExpr(ObjCSuperExpr *E) {
+  VisitExpr(E);
+  Writer.AddSourceLocation(E->getLoc(), Record);
+
+}
+
 
 //===----------------------------------------------------------------------===//
 // PCHWriter Implementation