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 /include | |
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
Diffstat (limited to 'include')
-rw-r--r-- | include/clang/AST/Expr.h | 35 |
1 files changed, 28 insertions, 7 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 |