diff options
author | Ted Kremenek <kremenek@apple.com> | 2008-05-01 17:26:20 +0000 |
---|---|---|
committer | Ted Kremenek <kremenek@apple.com> | 2008-05-01 17:26:20 +0000 |
commit | ea958e57a370b641c5a69347b75e9f8e3b5a41a2 (patch) | |
tree | bbdd104a583c9db6dac9fff848ad2600d0ba49ad | |
parent | c7122d5dd2aba01a59259f1f659bf59eca30d7e6 (diff) |
Use pointer swizziling to unify in ObjCMessageExpr the receiver and classname "fields". This saves us a pointer.
Implemented serialization for ObjCMessageExpr.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@50528 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/AST/Expr.h | 35 | ||||
-rw-r--r-- | lib/AST/Expr.cpp | 11 | ||||
-rw-r--r-- | lib/AST/StmtDumper.cpp | 2 | ||||
-rw-r--r-- | lib/AST/StmtSerialization.cpp | 61 |
4 files changed, 93 insertions, 16 deletions
diff --git a/include/clang/AST/Expr.h b/include/clang/AST/Expr.h index df0ea77267..824fd4d6c8 100644 --- a/include/clang/AST/Expr.h +++ b/include/clang/AST/Expr.h @@ -1518,10 +1518,16 @@ class ObjCMessageExpr : public Expr { // FIXME: Since method decls contain the selector, and most messages have a // prototype, consider devising a scheme for unifying SelName/MethodProto. ObjCMethodDecl *MethodProto; + + SourceLocation LBracloc, RBracloc; - IdentifierInfo *ClassName; // optional - 0 for instance messages. + // constructor used during deserialization + ObjCMessageExpr(Selector selInfo, QualType retType, + SourceLocation LBrac, SourceLocation RBrac, + Expr **ArgExprs, unsigned nargs) + : Expr(ObjCMessageExprClass, retType), NumArgs(nargs), SelName(selInfo), + MethodProto(NULL), LBracloc(LBrac), RBracloc(RBrac) {} - SourceLocation LBracloc, RBracloc; public: // constructor for class messages. // FIXME: clsName should be typed to ObjCInterfaceType @@ -1534,6 +1540,7 @@ public: QualType retType, ObjCMethodDecl *methDecl, SourceLocation LBrac, SourceLocation RBrac, Expr **ArgExprs, unsigned NumArgs); + ~ObjCMessageExpr() { delete [] SubExprs; } @@ -1541,8 +1548,13 @@ public: /// getReceiver - Returns the receiver of the message expression. /// This can be NULL if the message is for instance methods. For /// instance methods, use getClassName. - const Expr *getReceiver() const { return SubExprs[RECEIVER]; } - Expr *getReceiver() { return SubExprs[RECEIVER]; } + Expr *getReceiver() { + uintptr_t x = (uintptr_t) SubExprs[RECEIVER]; + return x & 0x1 ? NULL : (Expr*) x; + } + const Expr *getReceiver() const { + return const_cast<ObjCMessageExpr*>(this)->getReceiver(); + } Selector getSelector() const { return SelName; } @@ -1551,8 +1563,13 @@ public: /// getClassName - For instance methods, this returns the invoked class, /// and returns NULL otherwise. For regular methods, use getReceiver. - const IdentifierInfo *getClassName() const { return ClassName; } - IdentifierInfo *getClassName() { return ClassName; } + IdentifierInfo *getClassName() { + uintptr_t x = (uintptr_t) SubExprs[RECEIVER]; + return x & 0x1 ? (IdentifierInfo*) (x & ~0x1) : NULL; + } + const IdentifierInfo *getClassName() const { + return const_cast<ObjCMessageExpr*>(this)->getClassName(); + } /// getNumArgs - Return the number of actual arguments to this call. unsigned getNumArgs() const { return NumArgs; } @@ -1591,7 +1608,11 @@ public: arg_iterator arg_begin() { return &SubExprs[ARGS_START]; } arg_iterator arg_end() { return arg_begin() + NumArgs; } const_arg_iterator arg_begin() const { return &SubExprs[ARGS_START]; } - const_arg_iterator arg_end() const { return arg_begin() + NumArgs; } + const_arg_iterator arg_end() const { return arg_begin() + NumArgs; } + + // Serialization. + virtual void EmitImpl(llvm::Serializer& S) const; + static ObjCMessageExpr* CreateImpl(llvm::Deserializer& D, ASTContext& C); }; } // end namespace clang diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 67e39b6480..479b651d1f 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -1091,7 +1091,7 @@ ObjCMessageExpr::ObjCMessageExpr(Expr *receiver, Selector selInfo, SourceLocation LBrac, SourceLocation RBrac, Expr **ArgExprs, unsigned nargs) : Expr(ObjCMessageExprClass, retType), SelName(selInfo), - MethodProto(mproto), ClassName(0) { + MethodProto(mproto) { NumArgs = nargs; SubExprs = new Expr*[NumArgs+1]; SubExprs[RECEIVER] = receiver; @@ -1110,10 +1110,10 @@ ObjCMessageExpr::ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo, SourceLocation LBrac, SourceLocation RBrac, Expr **ArgExprs, unsigned nargs) : Expr(ObjCMessageExprClass, retType), SelName(selInfo), - MethodProto(mproto), ClassName(clsName) { + MethodProto(mproto) { NumArgs = nargs; SubExprs = new Expr*[NumArgs+1]; - SubExprs[RECEIVER] = 0; + SubExprs[RECEIVER] = (Expr*) ((uintptr_t) clsName | 0x1); if (NumArgs) { for (unsigned i = 0; i != NumArgs; ++i) SubExprs[i+ARGS_START] = static_cast<Expr *>(ArgExprs[i]); @@ -1122,7 +1122,6 @@ ObjCMessageExpr::ObjCMessageExpr(IdentifierInfo *clsName, Selector selInfo, RBracloc = RBrac; } - bool ChooseExpr::isConditionTrue(ASTContext &C) const { llvm::APSInt CondVal(32); bool IsConst = getCond()->isIntegerConstantExpr(CondVal, C); @@ -1397,8 +1396,8 @@ Stmt::child_iterator ObjCProtocolExpr::child_end() { } // ObjCMessageExpr -Stmt::child_iterator ObjCMessageExpr::child_begin() { - return reinterpret_cast<Stmt**>(&SubExprs[0]); +Stmt::child_iterator ObjCMessageExpr::child_begin() { + return reinterpret_cast<Stmt**>(&SubExprs[ getReceiver() ? 0 : ARGS_START ]); } Stmt::child_iterator ObjCMessageExpr::child_end() { return reinterpret_cast<Stmt**>(&SubExprs[getNumArgs()+ARGS_START]); diff --git a/lib/AST/StmtDumper.cpp b/lib/AST/StmtDumper.cpp index 798ea84677..77fbad5faa 100644 --- a/lib/AST/StmtDumper.cpp +++ b/lib/AST/StmtDumper.cpp @@ -428,6 +428,8 @@ void StmtDumper::VisitCXXBoolLiteralExpr(CXXBoolLiteralExpr *Node) { void StmtDumper::VisitObjCMessageExpr(ObjCMessageExpr* Node) { DumpExpr(Node); fprintf(F, " selector=%s", Node->getSelector().getName().c_str()); + IdentifierInfo* clsName = Node->getClassName(); + if (clsName) fprintf(F, " class=%s", clsName->getName()); } void StmtDumper::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) { diff --git a/lib/AST/StmtSerialization.cpp b/lib/AST/StmtSerialization.cpp index 3bec743740..adaa559b06 100644 --- a/lib/AST/StmtSerialization.cpp +++ b/lib/AST/StmtSerialization.cpp @@ -181,6 +181,9 @@ Stmt* Stmt::Create(Deserializer& D, ASTContext& C) { case ObjCIvarRefExprClass: return ObjCIvarRefExpr::CreateImpl(D, C); + case ObjCMessageExprClass: + return ObjCMessageExpr::CreateImpl(D, C); + case ObjCSelectorExprClass: return ObjCSelectorExpr::CreateImpl(D, C); @@ -190,9 +193,9 @@ Stmt* Stmt::Create(Deserializer& D, ASTContext& C) { //==--------------------------------------==// // C++ //==--------------------------------------==// - case CXXDefaultArgExprClass: - return CXXDefaultArgExpr::CreateImpl(D, C); + case CXXDefaultArgExprClass: + return CXXDefaultArgExpr::CreateImpl(D, C); } } @@ -327,7 +330,7 @@ void CallExpr::EmitImpl(Serializer& S) const { S.Emit(getType()); S.Emit(RParenLoc); S.EmitInt(NumArgs); - S.BatchEmitOwnedPtrs(NumArgs+1,SubExprs); + S.BatchEmitOwnedPtrs(NumArgs+1, SubExprs); } CallExpr* CallExpr::CreateImpl(Deserializer& D, ASTContext& C) { @@ -984,6 +987,58 @@ ObjCIvarRefExpr* ObjCIvarRefExpr::CreateImpl(Deserializer& D, ASTContext& C) { return dr; } +void ObjCMessageExpr::EmitImpl(Serializer& S) const { + S.EmitBool(getReceiver() ? true : false); + S.Emit(getType()); + S.Emit(SelName); + S.Emit(LBracloc); + S.Emit(RBracloc); + S.EmitInt(NumArgs); + S.EmitPtr(MethodProto); + + if (getReceiver()) + S.BatchEmitOwnedPtrs(NumArgs+1, SubExprs); + else { + S.EmitPtr(getClassName()); + S.BatchEmitOwnedPtrs(NumArgs, &SubExprs[ARGS_START]); + } +} + +ObjCMessageExpr* ObjCMessageExpr::CreateImpl(Deserializer& D, ASTContext& C) { + bool isReceiver = D.ReadBool(); + QualType t = QualType::ReadVal(D); + Selector S = Selector::ReadVal(D); + SourceLocation L = SourceLocation::ReadVal(D); + SourceLocation R = SourceLocation::ReadVal(D); + + // Construct an array for the subexpressions. + unsigned NumArgs = D.ReadInt(); + Expr** SubExprs = new Expr*[NumArgs+1]; + + // Construct the ObjCMessageExpr object using the special ctor. + ObjCMessageExpr* ME = new ObjCMessageExpr(S, t, L, R, SubExprs, NumArgs); + + // Read in the MethodProto. Read the instance variable directly + // allows it to be backpatched. + D.ReadPtr(ME->MethodProto); + + // Now read in the arguments. + + if (isReceiver) + D.BatchReadOwnedPtrs(NumArgs+1, SubExprs, C); + else { + // Read the pointer for ClassName. The Deserializer will handle the + // bit-mangling automatically. + SubExprs[RECEIVER] = (Expr*) ((uintptr_t) 0x1); + D.ReadUIntPtr((uintptr_t&) SubExprs[RECEIVER]); + + // Read the arguments. + D.BatchReadOwnedPtrs(NumArgs, &SubExprs[ARGS_START], C); + } + + return ME; +} + void ObjCSelectorExpr::EmitImpl(Serializer& S) const { S.Emit(AtLoc); S.Emit(RParenLoc); |