aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--include/clang/AST/ExprObjC.h19
-rw-r--r--include/clang/Frontend/PCHBitCodes.h8
-rw-r--r--lib/Frontend/PCHReader.cpp19
-rw-r--r--lib/Frontend/PCHWriter.cpp16
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<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);
}
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<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.
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