From c4f0bbdb166fbc31ab2cf0f6ff573fde9fa307b3 Mon Sep 17 00:00:00 2001 From: Steve Naroff Date: Sat, 25 Apr 2009 14:04:28 +0000 Subject: [PATCH] Add PCH support for ObjCMessageExpr (needed to build Mail). git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@70044 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/clang/AST/ExprObjC.h | 19 +++++++++++++++---- include/clang/Frontend/PCHBitCodes.h | 8 +++++--- lib/Frontend/PCHReader.cpp | 19 +++++++++++++++++++ lib/Frontend/PCHWriter.cpp | 16 ++++++++++++++++ 4 files changed, 55 insertions(+), 7 deletions(-) diff --git a/include/clang/AST/ExprObjC.h b/include/clang/AST/ExprObjC.h index 05f26d1ec0..d03956cf0b 100644 --- a/include/clang/AST/ExprObjC.h +++ b/include/clang/AST/ExprObjC.h @@ -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(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 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); } diff --git a/include/clang/Frontend/PCHBitCodes.h b/include/clang/Frontend/PCHBitCodes.h index b84d2edecf..ba9d3e4c9d 100644 --- a/include/clang/Frontend/PCHBitCodes.h +++ b/include/clang/Frontend/PCHBitCodes.h @@ -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 diff --git a/lib/Frontend/PCHReader.cpp b/lib/Frontend/PCHReader.cpp index 300761a0e5..26b915800a 100644 --- a/lib/Frontend/PCHReader.cpp +++ b/lib/Frontend/PCHReader.cpp @@ -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(Reader.GetDecl(Record[Idx++]))); + // FIXME: deal with class messages. + E->setReceiver(cast(StmtStack[StmtStack.size() - E->getNumArgs() - 1])); + for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I) + E->setArg(I, cast(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. diff --git a/lib/Frontend/PCHWriter.cpp b/lib/Frontend/PCHWriter.cpp index 5a410b1cf8..f8c4a779fb 100644 --- a/lib/Frontend/PCHWriter.cpp +++ b/lib/Frontend/PCHWriter.cpp @@ -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 -- 2.40.0