QualType retType, ObjCMethodDecl *methDecl,
SourceLocation LBrac, SourceLocation RBrac,
Expr **ArgExprs, unsigned NumArgs);
+
+ explicit ObjCMessageExpr(EmptyShell Empty)
+ : Expr(ObjCMessageExprClass, Empty) {}
~ObjCMessageExpr() {
delete [] SubExprs;
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*
/// 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!");
SubExprs[Arg+ARGS_START] = ArgExpr;
}
+ void setSourceRange(SourceRange R) {
+ LBracloc = R.getBegin();
+ RBracloc = R.getEnd();
+ }
virtual SourceRange getSourceRange() const {
return SourceRange(LBracloc, RBracloc);
}
/// \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
unsigned VisitObjCEncodeExpr(ObjCEncodeExpr *E);
unsigned VisitObjCSelectorExpr(ObjCSelectorExpr *E);
unsigned VisitObjCProtocolExpr(ObjCProtocolExpr *E);
+ unsigned VisitObjCMessageExpr(ObjCMessageExpr *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
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.
void VisitObjCEncodeExpr(ObjCEncodeExpr *E);
void VisitObjCSelectorExpr(ObjCSelectorExpr *E);
void VisitObjCProtocolExpr(ObjCProtocolExpr *E);
+ void VisitObjCMessageExpr(ObjCMessageExpr *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