[cfe-commits] r101972 - in /cfe/trunk: include/clang/AST/ include/clang/Checker/BugReporter/ lib/AST/ lib/Checker/ lib/CodeGen/ lib/Frontend/ lib/Index/ lib/Sema/ tools/CIndex/

Douglas Gregor dgregor at apple.com
Tue Apr 20 17:45:42 PDT 2010


Author: dgregor
Date: Tue Apr 20 19:45:42 2010
New Revision: 101972

URL: http://llvm.org/viewvc/llvm-project?rev=101972&view=rev
Log:
Overhaul the AST representation of Objective-C message send
expressions, to improve source-location information, clarify the
actual receiver of the message, and pave the way for proper C++
support. The ObjCMessageExpr node represents four different kinds of
message sends in a single AST node:

  1) Send to a object instance described by an expression (e.g., [x method:5])
  2) Send to a class described by the class name (e.g., [NSString method:5])
  3) Send to a superclass class (e.g, [super method:5] in class method)
  4) Send to a superclass instance (e.g., [super method:5] in instance method)

Previously these four cases where tangled together. Now, they have
more distinct representations. Specific changes:

  1) Unchanged; the object instance is represented by an Expr*.

  2) Previously stored the ObjCInterfaceDecl* referring to the class
  receiving the message. Now stores a TypeSourceInfo* so that we know
  how the class was spelled. This both maintains typedef information
  and opens the door for more complicated C++ types (e.g., dependent
  types). There was an alternative, unused representation of these
  sends by naming the class via an IdentifierInfo *. In practice, we
  either had an ObjCInterfaceDecl *, from which we would get the
  IdentifierInfo *, or we fell into the case below...

  3) Previously represented by a class message whose IdentifierInfo *
  referred to "super". Sema and CodeGen would use isStr("super") to
  determine if they had a send to super. Now represented as a
  "class super" send, where we have both the location of the "super"
  keyword and the ObjCInterfaceDecl* of the superclass we're
  targetting (statically).

  4) Previously represented by an instance message whose receiver is a
  an ObjCSuperExpr, which Sema and CodeGen would check for via
  isa<ObjCSuperExpr>(). Now represented as an "instance super" send,
  where we have both the location of the "super" keyword and the
  ObjCInterfaceDecl* of the superclass we're targetting
  (statically). Note that ObjCSuperExpr only has one remaining use in
  the AST, which is for "super.prop" references.

The new representation of ObjCMessageExpr is 2 pointers smaller than
the old one, since it combines more storage. It also eliminates a leak
when we loaded message-send expressions from a precompiled header. The
representation also feels much cleaner to me; comments welcome!

This patch attempts to maintain the same semantics we previously had
with Objective-C message sends. In several places, there are massive
changes that boil down to simply replacing a nested-if structure such
as:

  if (message has a receiver expression) {
    // instance message
    if (isa<ObjCSuperExpr>(...)) {
     // send to super
    } else {
     // send to an object
   }
  } else {
    // class message
    if (name->isStr("super")) {
      // class send to super
    } else {
      // send to class
    }
  }

with a switch

  switch (E->getReceiverKind()) {
  case ObjCMessageExpr::SuperInstance: ...
  case ObjCMessageExpr::Instance: ...
  case ObjCMessageExpr::SuperClass: ...
  case ObjCMessageExpr::Class:...
  }

There are quite a few places (particularly in the checkers) where
send-to-super is effectively ignored. I've placed FIXMEs in most of
them, and attempted to address send-to-super in a reasonable way. This
could use some review.


Modified:
    cfe/trunk/include/clang/AST/ExprObjC.h
    cfe/trunk/include/clang/Checker/BugReporter/BugReporter.h
    cfe/trunk/lib/AST/Expr.cpp
    cfe/trunk/lib/AST/StmtDumper.cpp
    cfe/trunk/lib/AST/StmtPrinter.cpp
    cfe/trunk/lib/Checker/BasicObjCFoundationChecks.cpp
    cfe/trunk/lib/Checker/BugReporterVisitors.cpp
    cfe/trunk/lib/Checker/CFRefCount.cpp
    cfe/trunk/lib/Checker/CallAndMessageChecker.cpp
    cfe/trunk/lib/Checker/CheckObjCDealloc.cpp
    cfe/trunk/lib/Checker/GRExprEngine.cpp
    cfe/trunk/lib/Checker/NSAutoreleasePoolChecker.cpp
    cfe/trunk/lib/CodeGen/CGObjC.cpp
    cfe/trunk/lib/Frontend/PCHReaderStmt.cpp
    cfe/trunk/lib/Frontend/PCHWriterStmt.cpp
    cfe/trunk/lib/Frontend/RewriteObjC.cpp
    cfe/trunk/lib/Index/Analyzer.cpp
    cfe/trunk/lib/Sema/SemaCodeComplete.cpp
    cfe/trunk/lib/Sema/SemaExpr.cpp
    cfe/trunk/lib/Sema/SemaExprObjC.cpp
    cfe/trunk/tools/CIndex/CIndex.cpp

Modified: cfe/trunk/include/clang/AST/ExprObjC.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ExprObjC.h?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ExprObjC.h (original)
+++ cfe/trunk/include/clang/AST/ExprObjC.h Tue Apr 20 19:45:42 2010
@@ -344,151 +344,352 @@
 };
 
 class ObjCMessageExpr : public Expr {
-  // SubExprs - The receiver and arguments of the message expression.
-  Stmt **SubExprs;
-
-  // NumArgs - The number of arguments (not including the receiver) to the
-  //  message expression.
-  unsigned NumArgs;
-
-  /// \brief The location of the class name in a class message.
-  SourceLocation ClassNameLoc;
-
-  // A unigue name for this message.
-  Selector SelName;
-
-  // A method prototype for this message (optional).
-  // 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;
-
-  // Constants for indexing into SubExprs.
-  enum { RECEIVER=0, ARGS_START=1 };
-
-  // Bit-swizzling flags.
-  enum { IsInstMeth=0, IsClsMethDeclUnknown, IsClsMethDeclKnown, Flags=0x3 };
-  unsigned getFlag() const { return (uintptr_t) SubExprs[RECEIVER] & Flags; }
+  /// \brief The number of arguments in the message send, not
+  /// including the receiver.
+  unsigned NumArgs : 16;
+
+  /// \brief The kind of message send this is, which is one of the
+  /// ReceiverKind values.
+  ///
+  /// We pad this out to a byte to avoid excessive masking and shifting.
+  unsigned Kind : 8;
+
+  /// \brief Whether we have an actual method prototype in \c
+  /// SelectorOrMethod.
+  ///
+  /// When non-zero, we have a method declaration; otherwise, we just
+  /// have a selector.
+  unsigned HasMethod : 8;
+
+  /// \brief When the message expression is a send to 'super', this is
+  /// the location of the 'super' keyword.
+  SourceLocation SuperLoc;
+
+  /// \brief Stores either the selector that this message is sending
+  /// to (when \c HasMethod is zero) or an \c ObjCMethodDecl pointer
+  /// referring to the method that we type-checked against.
+  uintptr_t SelectorOrMethod;
+
+  /// \brief The source locations of the open and close square
+  /// brackets ('[' and ']', respectively).
+  SourceLocation LBracLoc, RBracLoc;
+
+  ObjCMessageExpr(EmptyShell Empty, unsigned NumArgs)
+    : Expr(ObjCMessageExprClass, Empty), NumArgs(NumArgs), Kind(0), 
+      HasMethod(0), SelectorOrMethod(0) { }
+
+  ObjCMessageExpr(QualType T,
+                  SourceLocation LBracLoc,
+                  SourceLocation SuperLoc,
+                  bool IsInstanceSuper,
+                  QualType SuperType,
+                  Selector Sel, 
+                  ObjCMethodDecl *Method,
+                  Expr **Args, unsigned NumArgs,
+                  SourceLocation RBracLoc);
+  ObjCMessageExpr(QualType T,
+                  SourceLocation LBracLoc,
+                  TypeSourceInfo *Receiver,
+                  Selector Sel, 
+                  ObjCMethodDecl *Method,
+                  Expr **Args, unsigned NumArgs,
+                  SourceLocation RBracLoc);
+  ObjCMessageExpr(QualType T,
+                  SourceLocation LBracLoc,
+                  Expr *Receiver,
+                  Selector Sel, 
+                  ObjCMethodDecl *Method,
+                  Expr **Args, unsigned NumArgs,
+                  SourceLocation RBracLoc);
+
+  /// \brief Retrieve the pointer value of the ,essage receiver.
+  void *getReceiverPointer() const {
+    return *const_cast<void **>(
+                             reinterpret_cast<const void * const*>(this + 1));
+  }
+
+  /// \brief Set the pointer value of the message receiver.
+  void setReceiverPointer(void *Value) {
+    *reinterpret_cast<void **>(this + 1) = Value;
+  }
 
 public:
-  /// This constructor is used to represent class messages where the
-  /// ObjCInterfaceDecl* of the receiver is not known.
-  ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName, 
-                  SourceLocation clsNameLoc, Selector selInfo,
-                  QualType retType, ObjCMethodDecl *methDecl,
-                  SourceLocation LBrac, SourceLocation RBrac,
-                  Expr **ArgExprs, unsigned NumArgs);
-
-  /// This constructor is used to represent class messages where the
-  /// ObjCInterfaceDecl* of the receiver is known.
-  // FIXME: clsName should be typed to ObjCInterfaceType
-  ObjCMessageExpr(ASTContext &C, ObjCInterfaceDecl *cls, 
-                  SourceLocation clsNameLoc, Selector selInfo,
-                  QualType retType, ObjCMethodDecl *methDecl,
-                  SourceLocation LBrac, SourceLocation RBrac,
-                  Expr **ArgExprs, unsigned NumArgs);
-
-  // constructor for instance messages.
-  ObjCMessageExpr(ASTContext &C, Expr *receiver, Selector selInfo,
-                  QualType retType, ObjCMethodDecl *methDecl,
-                  SourceLocation LBrac, SourceLocation RBrac,
-                  Expr **ArgExprs, unsigned NumArgs);
-
-  explicit ObjCMessageExpr(EmptyShell Empty)
-    : Expr(ObjCMessageExprClass, Empty), SubExprs(0), NumArgs(0) {}
-
-  virtual void DoDestroy(ASTContext &C);
-
-  /// getReceiver - Returns the receiver of the message expression.
-  ///  This can be NULL if the message is for class methods.  For
-  ///  class methods, use getClassName.
-  /// FIXME: need to handle/detect 'super' usage within a class method.
-  Expr *getReceiver() {
-    uintptr_t x = (uintptr_t) SubExprs[RECEIVER];
-    return (x & Flags) == IsInstMeth ? (Expr*) x : 0;
-  }
-  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; }
-
-  /// \brief Describes the class receiver of a message send.
-  struct ClassInfo {
-    /// \brief The interface declaration for the class that is
-    /// receiving the message. May be NULL.
-    ObjCInterfaceDecl *Decl;
-
-    /// \brief The name of the class that is receiving the
-    /// message. This will never be NULL.
-    IdentifierInfo *Name;
-
-    /// \brief The source location of the class name.
-    SourceLocation Loc;
-
-    ClassInfo() : Decl(0), Name(0), Loc() { }
-
-    ClassInfo(ObjCInterfaceDecl *Decl, IdentifierInfo *Name, SourceLocation Loc)
-      : Decl(Decl), Name(Name), Loc(Loc) { }
+  /// \brief The kind of receiver this message is sending to.
+  enum ReceiverKind {
+    /// \brief The receiver is a class.
+    Class = 0,
+    /// \brief The receiver is an object instance.
+    Instance,
+    /// \brief The receiver is a superclass.
+    SuperClass,
+    /// \brief The receiver is the instance of the superclass object.
+    SuperInstance
   };
 
-  /// getClassInfo - For class methods, this returns both the ObjCInterfaceDecl*
-  ///  and IdentifierInfo* of the invoked class.  Both can be NULL if this
-  ///  is an instance message, and the ObjCInterfaceDecl* can be NULL if none
-  ///  was available when this ObjCMessageExpr object was constructed.
-  ClassInfo getClassInfo() const;
-  void setClassInfo(const ClassInfo &C);
-
-  /// getClassName - For class methods, this returns the invoked class,
-  ///  and returns NULL otherwise.  For instance methods, use getReceiver.
-  IdentifierInfo *getClassName() const {
-    return getClassInfo().Name;
+  /// \brief Create a message send to super.
+  ///
+  /// \param Context The ASTContext in which this expression will be created.
+  ///
+  /// \param T The result type of this message.
+  ///
+  /// \param LBrac The location of the open square bracket '['.
+  ///
+  /// \param SuperLoc The location of the "super" keyword.
+  ///
+  /// \param IsInstanceSuper Whether this is an instance "super"
+  /// message (otherwise, it's a class "super" message).
+  ///
+  /// \param Sel The selector used to determine which method gets called.
+  ///
+  /// \param Method The Objective-C method against which this message
+  /// send was type-checked. May be NULL.
+  ///
+  /// \param Args The message send arguments.
+  ///
+  /// \param NumArgs The number of arguments.
+  ///
+  /// \param RBracLoc The location of the closing square bracket ']'.
+  static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
+                                 SourceLocation LBracLoc,
+                                 SourceLocation SuperLoc,
+                                 bool IsInstanceSuper,
+                                 QualType SuperType,
+                                 Selector Sel, 
+                                 ObjCMethodDecl *Method,
+                                 Expr **Args, unsigned NumArgs,
+                                 SourceLocation RBracLoc);
+
+  /// \brief Create a class message send.
+  ///
+  /// \param Context The ASTContext in which this expression will be created.
+  ///
+  /// \param T The result type of this message.
+  ///
+  /// \param LBrac The location of the open square bracket '['.
+  ///
+  /// \param Receiver The type of the receiver, including
+  /// source-location information.
+  ///
+  /// \param Sel The selector used to determine which method gets called.
+  ///
+  /// \param Method The Objective-C method against which this message
+  /// send was type-checked. May be NULL.
+  ///
+  /// \param Args The message send arguments.
+  ///
+  /// \param NumArgs The number of arguments.
+  ///
+  /// \param RBracLoc The location of the closing square bracket ']'.
+  static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
+                                 SourceLocation LBracLoc,
+                                 TypeSourceInfo *Receiver,
+                                 Selector Sel, 
+                                 ObjCMethodDecl *Method,
+                                 Expr **Args, unsigned NumArgs,
+                                 SourceLocation RBracLoc);
+
+  /// \brief Create an instance message send.
+  ///
+  /// \param Context The ASTContext in which this expression will be created.
+  ///
+  /// \param T The result type of this message.
+  ///
+  /// \param LBrac The location of the open square bracket '['.
+  ///
+  /// \param Receiver The expression used to produce the object that
+  /// will receive this message.
+  ///
+  /// \param Sel The selector used to determine which method gets called.
+  ///
+  /// \param Method The Objective-C method against which this message
+  /// send was type-checked. May be NULL.
+  ///
+  /// \param Args The message send arguments.
+  ///
+  /// \param NumArgs The number of arguments.
+  ///
+  /// \param RBracLoc The location of the closing square bracket ']'.
+  static ObjCMessageExpr *Create(ASTContext &Context, QualType T,
+                                 SourceLocation LBracLoc,
+                                 Expr *Receiver,
+                                 Selector Sel, 
+                                 ObjCMethodDecl *Method,
+                                 Expr **Args, unsigned NumArgs,
+                                 SourceLocation RBracLoc);
+
+  /// \brief Create an empty Objective-C message expression, to be
+  /// filled in by subsequent calls.
+  ///
+  /// \param Context The context in which the message send will be created.
+  ///
+  /// \param NumArgs The number of message arguments, not including
+  /// the receiver.
+  static ObjCMessageExpr *CreateEmpty(ASTContext &Context, unsigned NumArgs);
+
+  /// \brief Determine the kind of receiver that this message is being
+  /// sent to.
+  ReceiverKind getReceiverKind() const { return (ReceiverKind)Kind; }
+
+  /// \brief Determine whether this is an instance message to either a
+  /// computed object or to super.
+  bool isInstanceMessage() const {
+    return getReceiverKind() == Instance || getReceiverKind() == SuperInstance;
+  }
+
+  /// \brief Determine whether this is an class message to either a
+  /// specified class or to super.
+  bool isClassMessage() const {
+    return getReceiverKind() == Class || getReceiverKind() == SuperClass;
+  }
+
+  /// \brief Returns the receiver of an instance message.
+  ///
+  /// \brief Returns the object expression for an instance message, or
+  /// NULL for a message that is not an instance message.
+  Expr *getInstanceReceiver() {
+    if (getReceiverKind() == Instance)
+      return static_cast<Expr *>(getReceiverPointer());
+
+    return 0;
+  }
+  const Expr *getInstanceReceiver() const {
+    return const_cast<ObjCMessageExpr*>(this)->getInstanceReceiver();
+  }
+
+  /// \brief Turn this message send into an instance message that
+  /// computes the receiver object with the given expression.
+  void setInstanceReceiver(Expr *rec) { 
+    Kind = Instance;
+    setReceiverPointer(rec);
+  }
+  
+  /// \brief Returns the type of a class message send, or NULL if the
+  /// message is not a class message.
+  QualType getClassReceiver() const { 
+    if (TypeSourceInfo *TSInfo = getClassReceiverTypeInfo())
+      return TSInfo->getType();
+
+    return QualType();
+  }
+
+  /// \brief Returns a type-source information of a class message
+  /// send, or NULL if the message is not a class message.
+  TypeSourceInfo *getClassReceiverTypeInfo() const {
+    if (getReceiverKind() == Class)
+      return reinterpret_cast<TypeSourceInfo *>(getReceiverPointer());
+    return 0;
+  }
+
+  void setClassReceiver(TypeSourceInfo *TSInfo) {
+    Kind = Class;
+    setReceiverPointer(TSInfo);
+  }
+
+  /// \brief Retrieve the location of the 'super' keyword for a class
+  /// or instance message to 'super', otherwise an invalid source location.
+  SourceLocation getSuperLoc() const { 
+    if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
+      return SuperLoc;
+
+    return SourceLocation();
+  }
+
+  /// \brief Retrieve the Objective-C interface to which this message
+  /// is being directed, if known.
+  ///
+  /// This routine cross-cuts all of the different kinds of message
+  /// sends to determine what the underlying (statically known) type
+  /// of the receiver will be; use \c getReceiverKind() to determine
+  /// whether the message is a class or an instance method, whether it
+  /// is a send to super or not, etc.
+  ///
+  /// \returns The Objective-C interface if known, otherwise NULL.
+  ObjCInterfaceDecl *getReceiverInterface() const;
+
+  /// \brief Retrieve the type referred to by 'super'. 
+  ///
+  /// The returned type will either be an ObjCInterfaceType (for an
+  /// class message to super) or an ObjCObjectPointerType that refers
+  /// to a class (for an instance message to super);
+  QualType getSuperType() const {
+    if (getReceiverKind() == SuperInstance || getReceiverKind() == SuperClass)
+      return QualType::getFromOpaquePtr(getReceiverPointer());
+
+    return QualType();
+  }
+
+  void setSuper(SourceLocation Loc, QualType T, bool IsInstanceSuper) {
+    Kind = IsInstanceSuper? SuperInstance : SuperClass;
+    SuperLoc = Loc;
+    setReceiverPointer(T.getAsOpaquePtr());
+  }
+
+  Selector getSelector() const;
+
+  void setSelector(Selector S) { 
+    HasMethod = false;
+    SelectorOrMethod = reinterpret_cast<uintptr_t>(S.getAsOpaquePtr());
+  }
+
+  const ObjCMethodDecl *getMethodDecl() const { 
+    if (HasMethod)
+      return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod);
+
+    return 0;
+  }
+
+  ObjCMethodDecl *getMethodDecl() { 
+    if (HasMethod)
+      return reinterpret_cast<ObjCMethodDecl *>(SelectorOrMethod);
+
+    return 0;
+  }
+
+  void setMethodDecl(ObjCMethodDecl *MD) { 
+    HasMethod = true;
+    SelectorOrMethod = reinterpret_cast<uintptr_t>(MD);
   }
 
-  /// getNumArgs - Return the number of actual arguments to this call.
+  /// \brief Return the number of actual arguments in this message,
+  /// not counting the receiver.
   unsigned getNumArgs() const { return NumArgs; }
-  void setNumArgs(unsigned nArgs) {
-    NumArgs = nArgs;
-    // FIXME: should always allocate SubExprs via the ASTContext's
-    // allocator.
-    if (!SubExprs)
-      SubExprs = new Stmt* [NumArgs + 1];
+
+  /// \brief Retrieve the arguments to this message, not including the
+  /// receiver.
+  Stmt **getArgs() {
+    return reinterpret_cast<Stmt **>(this + 1) + 1;
+  }
+  const Stmt * const *getArgs() const {
+    return reinterpret_cast<const Stmt * const *>(this + 1) + 1;
   }
 
   /// getArg - Return the specified argument.
   Expr *getArg(unsigned Arg) {
     assert(Arg < NumArgs && "Arg access out of range!");
-    return cast<Expr>(SubExprs[Arg+ARGS_START]);
+    return cast<Expr>(getArgs()[Arg]);
   }
   const Expr *getArg(unsigned Arg) const {
     assert(Arg < NumArgs && "Arg access out of range!");
-    return cast<Expr>(SubExprs[Arg+ARGS_START]);
+    return cast<Expr>(getArgs()[Arg]);
   }
   /// setArg - Set the specified argument.
   void setArg(unsigned Arg, Expr *ArgExpr) {
     assert(Arg < NumArgs && "Arg access out of range!");
-    SubExprs[Arg+ARGS_START] = ArgExpr;
+    getArgs()[Arg] = ArgExpr;
   }
 
-  SourceLocation getLeftLoc() const { return LBracloc; }
-  SourceLocation getRightLoc() const { return RBracloc; }
+  SourceLocation getLeftLoc() const { return LBracLoc; }
+  SourceLocation getRightLoc() const { return RBracLoc; }
 
-  void setLeftLoc(SourceLocation L) { LBracloc = L; }
-  void setRightLoc(SourceLocation L) { RBracloc = L; }
+  void setLeftLoc(SourceLocation L) { LBracLoc = L; }
+  void setRightLoc(SourceLocation L) { RBracLoc = L; }
 
   void setSourceRange(SourceRange R) {
-    LBracloc = R.getBegin();
-    RBracloc = R.getEnd();
+    LBracLoc = R.getBegin();
+    RBracLoc = R.getEnd();
   }
   virtual SourceRange getSourceRange() const {
-    return SourceRange(LBracloc, RBracloc);
+    return SourceRange(LBracLoc, RBracLoc);
   }
 
   static bool classof(const Stmt *T) {
@@ -503,10 +704,10 @@
   typedef ExprIterator arg_iterator;
   typedef ConstExprIterator const_arg_iterator;
 
-  arg_iterator arg_begin() { return &SubExprs[ARGS_START]; }
-  arg_iterator arg_end()   { return &SubExprs[ARGS_START] + NumArgs; }
-  const_arg_iterator arg_begin() const { return &SubExprs[ARGS_START]; }
-  const_arg_iterator arg_end() const { return &SubExprs[ARGS_START] + NumArgs; }
+  arg_iterator arg_begin() { return getArgs(); }
+  arg_iterator arg_end()   { return getArgs() + NumArgs; }
+  const_arg_iterator arg_begin() const { return (Stmt **)getArgs(); }
+  const_arg_iterator arg_end() const { return (Stmt **)getArgs() + NumArgs; }
 };
 
 /// ObjCSuperExpr - Represents the "super" expression in Objective-C,

Modified: cfe/trunk/include/clang/Checker/BugReporter/BugReporter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Checker/BugReporter/BugReporter.h?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/include/clang/Checker/BugReporter/BugReporter.h (original)
+++ cfe/trunk/include/clang/Checker/BugReporter/BugReporter.h Tue Apr 20 19:45:42 2010
@@ -458,7 +458,6 @@
 namespace bugreporter {
 
 const Stmt *GetDerefExpr(const ExplodedNode *N);
-const Stmt *GetReceiverExpr(const ExplodedNode *N);
 const Stmt *GetDenomExpr(const ExplodedNode *N);
 const Stmt *GetCalleeExpr(const ExplodedNode *N);
 const Stmt *GetRetValExpr(const ExplodedNode *N);

Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Tue Apr 20 19:45:42 2010
@@ -2239,101 +2239,156 @@
   }
 }
 
-// constructor for instance messages.
-ObjCMessageExpr::ObjCMessageExpr(ASTContext &C, Expr *receiver,
-                                 Selector selInfo,
-                                 QualType retType, ObjCMethodDecl *mproto,
-                                 SourceLocation LBrac, SourceLocation RBrac,
-                                 Expr **ArgExprs, unsigned nargs)
-  : Expr(ObjCMessageExprClass, retType, false, false), SelName(selInfo),
-    MethodProto(mproto) {
-  NumArgs = nargs;
-  SubExprs = new (C) Stmt*[NumArgs+1];
-  SubExprs[RECEIVER] = receiver;
-  if (NumArgs) {
-    for (unsigned i = 0; i != NumArgs; ++i)
-      SubExprs[i+ARGS_START] = static_cast<Expr *>(ArgExprs[i]);
-  }
-  LBracloc = LBrac;
-  RBracloc = RBrac;
-}
-
-// constructor for class messages.
-// FIXME: clsName should be typed to ObjCInterfaceType
-ObjCMessageExpr::ObjCMessageExpr(ASTContext &C, IdentifierInfo *clsName,
-                                 SourceLocation clsNameLoc, Selector selInfo, 
-                                 QualType retType, ObjCMethodDecl *mproto,
-                                 SourceLocation LBrac, SourceLocation RBrac,
-                                 Expr **ArgExprs, unsigned nargs)
-  : Expr(ObjCMessageExprClass, retType, false, false), ClassNameLoc(clsNameLoc),
-    SelName(selInfo), MethodProto(mproto) {
-  NumArgs = nargs;
-  SubExprs = new (C) Stmt*[NumArgs+1];
-  SubExprs[RECEIVER] = (Expr*) ((uintptr_t) clsName | IsClsMethDeclUnknown);
-  if (NumArgs) {
-    for (unsigned i = 0; i != NumArgs; ++i)
-      SubExprs[i+ARGS_START] = static_cast<Expr *>(ArgExprs[i]);
-  }
-  LBracloc = LBrac;
-  RBracloc = RBrac;
-}
-
-// constructor for class messages.
-ObjCMessageExpr::ObjCMessageExpr(ASTContext &C, ObjCInterfaceDecl *cls,
-                                 SourceLocation clsNameLoc, Selector selInfo, 
-                                 QualType retType,
-                                 ObjCMethodDecl *mproto, SourceLocation LBrac,
-                                 SourceLocation RBrac, Expr **ArgExprs,
-                                 unsigned nargs)
-  : Expr(ObjCMessageExprClass, retType, false, false), ClassNameLoc(clsNameLoc),
-    SelName(selInfo), MethodProto(mproto) 
+ObjCMessageExpr::ObjCMessageExpr(QualType T,
+                                 SourceLocation LBracLoc,
+                                 SourceLocation SuperLoc,
+                                 bool IsInstanceSuper,
+                                 QualType SuperType,
+                                 Selector Sel, 
+                                 ObjCMethodDecl *Method,
+                                 Expr **Args, unsigned NumArgs,
+                                 SourceLocation RBracLoc)
+  : Expr(ObjCMessageExprClass, T, /*TypeDependent=*/false,
+         hasAnyValueDependentArguments(Args, NumArgs)),
+    NumArgs(NumArgs), Kind(IsInstanceSuper? SuperInstance : SuperClass),
+    HasMethod(Method != 0), SuperLoc(SuperLoc),
+    SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
+                                                       : Sel.getAsOpaquePtr())),
+    LBracLoc(LBracLoc), RBracLoc(RBracLoc) 
 {
-  NumArgs = nargs;
-  SubExprs = new (C) Stmt*[NumArgs+1];
-  SubExprs[RECEIVER] = (Expr*) ((uintptr_t) cls | IsClsMethDeclKnown);
-  if (NumArgs) {
-    for (unsigned i = 0; i != NumArgs; ++i)
-      SubExprs[i+ARGS_START] = static_cast<Expr *>(ArgExprs[i]);
-  }
-  LBracloc = LBrac;
-  RBracloc = RBrac;
-}
-
-ObjCMessageExpr::ClassInfo ObjCMessageExpr::getClassInfo() const {
-  uintptr_t x = (uintptr_t) SubExprs[RECEIVER];
-  switch (x & Flags) {
-    default:
-      assert(false && "Invalid ObjCMessageExpr.");
-    case IsInstMeth:
-      return ClassInfo(0, 0, SourceLocation());
-    case IsClsMethDeclUnknown:
-      return ClassInfo(0, (IdentifierInfo*) (x & ~Flags), ClassNameLoc);
-    case IsClsMethDeclKnown: {
-      ObjCInterfaceDecl* D = (ObjCInterfaceDecl*) (x & ~Flags);
-      return ClassInfo(D, D->getIdentifier(), ClassNameLoc);
-    }
-  }
-}
-
-void ObjCMessageExpr::setClassInfo(const ObjCMessageExpr::ClassInfo &CI) {
-  if (CI.Decl == 0 && CI.Name == 0) {
-    SubExprs[RECEIVER] = (Expr*)((uintptr_t)0 | IsInstMeth);
-    return;
+  setReceiverPointer(SuperType.getAsOpaquePtr());
+  if (NumArgs)
+    memcpy(getArgs(), Args, NumArgs * sizeof(Expr *));
+}
+
+ObjCMessageExpr::ObjCMessageExpr(QualType T,
+                                 SourceLocation LBracLoc,
+                                 TypeSourceInfo *Receiver,
+                                 Selector Sel, 
+                                 ObjCMethodDecl *Method,
+                                 Expr **Args, unsigned NumArgs,
+                                 SourceLocation RBracLoc)
+  : Expr(ObjCMessageExprClass, T, T->isDependentType(),
+         (T->isDependentType() || 
+          hasAnyValueDependentArguments(Args, NumArgs))),
+    NumArgs(NumArgs), Kind(Class), HasMethod(Method != 0),
+    SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
+                                                       : Sel.getAsOpaquePtr())),
+    LBracLoc(LBracLoc), RBracLoc(RBracLoc) 
+{
+  setReceiverPointer(Receiver);
+  if (NumArgs)
+    memcpy(getArgs(), Args, NumArgs * sizeof(Expr *));
+}
+
+ObjCMessageExpr::ObjCMessageExpr(QualType T,
+                                 SourceLocation LBracLoc,
+                                 Expr *Receiver,
+                                 Selector Sel, 
+                                 ObjCMethodDecl *Method,
+                                 Expr **Args, unsigned NumArgs,
+                                 SourceLocation RBracLoc)
+  : Expr(ObjCMessageExprClass, T, T->isDependentType(),
+         (T->isDependentType() || 
+          hasAnyValueDependentArguments(Args, NumArgs))),
+    NumArgs(NumArgs), Kind(Instance), HasMethod(Method != 0),
+    SelectorOrMethod(reinterpret_cast<uintptr_t>(Method? Method
+                                                       : Sel.getAsOpaquePtr())),
+    LBracLoc(LBracLoc), RBracLoc(RBracLoc) 
+{
+  setReceiverPointer(Receiver);
+  if (NumArgs)
+    memcpy(getArgs(), Args, NumArgs * sizeof(Expr *));
+}
+
+ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T,
+                                         SourceLocation LBracLoc,
+                                         SourceLocation SuperLoc,
+                                         bool IsInstanceSuper,
+                                         QualType SuperType,
+                                         Selector Sel, 
+                                         ObjCMethodDecl *Method,
+                                         Expr **Args, unsigned NumArgs,
+                                         SourceLocation RBracLoc) {
+  unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + 
+    NumArgs * sizeof(Expr *);
+  void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
+  return new (Mem) ObjCMessageExpr(T, LBracLoc, SuperLoc, IsInstanceSuper,
+                                   SuperType, Sel, Method, Args, NumArgs, 
+                                   RBracLoc);
+}
+
+ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T,
+                                         SourceLocation LBracLoc,
+                                         TypeSourceInfo *Receiver,
+                                         Selector Sel, 
+                                         ObjCMethodDecl *Method,
+                                         Expr **Args, unsigned NumArgs,
+                                         SourceLocation RBracLoc) {
+  unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + 
+    NumArgs * sizeof(Expr *);
+  void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
+  return new (Mem) ObjCMessageExpr(T, LBracLoc, Receiver, Sel, Method, Args, 
+                                   NumArgs, RBracLoc);
+}
+
+ObjCMessageExpr *ObjCMessageExpr::Create(ASTContext &Context, QualType T,
+                                         SourceLocation LBracLoc,
+                                         Expr *Receiver,
+                                         Selector Sel, 
+                                         ObjCMethodDecl *Method,
+                                         Expr **Args, unsigned NumArgs,
+                                         SourceLocation RBracLoc) {
+  unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + 
+    NumArgs * sizeof(Expr *);
+  void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
+  return new (Mem) ObjCMessageExpr(T, LBracLoc, Receiver, Sel, Method, Args, 
+                                   NumArgs, RBracLoc);
+}
+
+ObjCMessageExpr *ObjCMessageExpr::CreateEmpty(ASTContext &Context, 
+                                              unsigned NumArgs) {
+  unsigned Size = sizeof(ObjCMessageExpr) + sizeof(void *) + 
+    NumArgs * sizeof(Expr *);
+  void *Mem = Context.Allocate(Size, llvm::AlignOf<ObjCMessageExpr>::Alignment);
+  return new (Mem) ObjCMessageExpr(EmptyShell(), NumArgs);
+}
+         
+Selector ObjCMessageExpr::getSelector() const {
+  if (HasMethod)
+    return reinterpret_cast<const ObjCMethodDecl *>(SelectorOrMethod)
+                                                               ->getSelector();
+  return Selector(SelectorOrMethod); 
+}
+
+ObjCInterfaceDecl *ObjCMessageExpr::getReceiverInterface() const {
+  switch (getReceiverKind()) {
+  case Instance:
+    if (const ObjCObjectPointerType *Ptr
+          = getInstanceReceiver()->getType()->getAs<ObjCObjectPointerType>())
+      return Ptr->getInterfaceDecl();
+    break;
+
+  case Class:
+    if (const ObjCInterfaceType *Iface
+                       = getClassReceiver()->getAs<ObjCInterfaceType>())
+      return Iface->getDecl();
+    break;
+
+  case SuperInstance:
+    if (const ObjCObjectPointerType *Ptr
+          = getSuperType()->getAs<ObjCObjectPointerType>())
+      return Ptr->getInterfaceDecl();
+    break;
+
+  case SuperClass:
+    if (const ObjCObjectPointerType *Iface
+                       = getSuperType()->getAs<ObjCObjectPointerType>())
+      return Iface->getInterfaceDecl();
+    break;
   }
 
-  if (CI.Decl == 0)
-    SubExprs[RECEIVER] = (Expr*)((uintptr_t)CI.Name | IsClsMethDeclUnknown);
-  else
-    SubExprs[RECEIVER] = (Expr*)((uintptr_t)CI.Decl | IsClsMethDeclKnown);
-  ClassNameLoc = CI.Loc;
-}
-
-void ObjCMessageExpr::DoDestroy(ASTContext &C) {
-  DestroyChildren(C);
-  if (SubExprs)
-    C.Deallocate(SubExprs);
-  this->~ObjCMessageExpr();
-  C.Deallocate((void*) this);
+  return 0;
 }
 
 bool ChooseExpr::isConditionTrue(ASTContext &C) const {
@@ -2809,10 +2864,12 @@
 
 // ObjCMessageExpr
 Stmt::child_iterator ObjCMessageExpr::child_begin() {
-  return getReceiver() ? &SubExprs[0] : &SubExprs[0] + ARGS_START;
+  if (getReceiverKind() == Instance)
+    return reinterpret_cast<Stmt **>(this + 1);
+  return getArgs();
 }
 Stmt::child_iterator ObjCMessageExpr::child_end() {
-  return &SubExprs[0]+ARGS_START+getNumArgs();
+  return getArgs() + getNumArgs();
 }
 
 // Blocks

Modified: cfe/trunk/lib/AST/StmtDumper.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtDumper.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtDumper.cpp (original)
+++ cfe/trunk/lib/AST/StmtDumper.cpp Tue Apr 20 19:45:42 2010
@@ -505,8 +505,23 @@
 void StmtDumper::VisitObjCMessageExpr(ObjCMessageExpr* Node) {
   DumpExpr(Node);
   OS << " selector=" << Node->getSelector().getAsString();
-  if (IdentifierInfo *clsName = Node->getClassName())
-    OS << " class=" << clsName->getNameStart();
+  switch (Node->getReceiverKind()) {
+  case ObjCMessageExpr::Instance:
+    break;
+
+  case ObjCMessageExpr::Class:
+    OS << " class=";
+    DumpType(Node->getClassReceiver());
+    break;
+
+  case ObjCMessageExpr::SuperInstance:
+    OS << " super (instance)";
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+    OS << " super (class)";
+    break;
+  }
 }
 
 void StmtDumper::VisitObjCEncodeExpr(ObjCEncodeExpr *Node) {

Modified: cfe/trunk/lib/AST/StmtPrinter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/StmtPrinter.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/AST/StmtPrinter.cpp (original)
+++ cfe/trunk/lib/AST/StmtPrinter.cpp Tue Apr 20 19:45:42 2010
@@ -1247,9 +1247,21 @@
 
 void StmtPrinter::VisitObjCMessageExpr(ObjCMessageExpr *Mess) {
   OS << "[";
-  Expr *receiver = Mess->getReceiver();
-  if (receiver) PrintExpr(receiver);
-  else OS << Mess->getClassName()->getName();
+  switch (Mess->getReceiverKind()) {
+  case ObjCMessageExpr::Instance:
+    PrintExpr(Mess->getInstanceReceiver());
+    break;
+
+  case ObjCMessageExpr::Class:
+    OS << Mess->getClassReceiver().getAsString(Policy);
+    break;
+
+  case ObjCMessageExpr::SuperInstance:
+  case ObjCMessageExpr::SuperClass:
+    OS << "Super";
+    break;
+  }
+
   OS << ' ';
   Selector selector = Mess->getSelector();
   if (selector.isUnarySelector()) {

Modified: cfe/trunk/lib/Checker/BasicObjCFoundationChecks.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/BasicObjCFoundationChecks.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/BasicObjCFoundationChecks.cpp (original)
+++ cfe/trunk/lib/Checker/BasicObjCFoundationChecks.cpp Tue Apr 20 19:45:42 2010
@@ -31,13 +31,22 @@
 using namespace clang;
 
 static const ObjCInterfaceType* GetReceiverType(const ObjCMessageExpr* ME) {
-  const Expr* Receiver = ME->getReceiver();
-
-  if (!Receiver)
-    return NULL;
+  QualType T;
+  switch (ME->getReceiverKind()) {
+  case ObjCMessageExpr::Instance:
+    T = ME->getInstanceReceiver()->getType();
+    break;
+
+  case ObjCMessageExpr::SuperInstance:
+    T = ME->getSuperType();
+    break;
+
+  case ObjCMessageExpr::Class:
+  case ObjCMessageExpr::SuperClass:
+    return 0;
+  }
 
-  if (const ObjCObjectPointerType *PT =
-      Receiver->getType()->getAs<ObjCObjectPointerType>())
+  if (const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>())
     return PT->getInterfaceType();
 
   return NULL;
@@ -509,11 +518,21 @@
 
 void ClassReleaseChecker::PreVisitObjCMessageExpr(CheckerContext &C,
                                                   const ObjCMessageExpr *ME) {
-  
-  const IdentifierInfo *ClsName = ME->getClassName();
-  if (!ClsName)
+  ObjCInterfaceDecl *Class = 0;
+  switch (ME->getReceiverKind()) {
+  case ObjCMessageExpr::Class:
+    Class = ME->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+    Class = ME->getSuperType()->getAs<ObjCInterfaceType>()->getDecl();
+    break;
+
+  case ObjCMessageExpr::Instance:
+  case ObjCMessageExpr::SuperInstance:
     return;
-  
+  }
+
   Selector S = ME->getSelector();
   if (!(S == releaseS || S == retainS || S == autoreleaseS || S == drainS))
     return;
@@ -531,7 +550,7 @@
   llvm::raw_svector_ostream os(buf);
 
   os << "The '" << S.getAsString() << "' message should be sent to instances "
-        "of class '" << ClsName->getName()
+        "of class '" << Class->getName()
      << "' and not the class directly";
   
   RangedBugReport *report = new RangedBugReport(*BT, os.str(), N);

Modified: cfe/trunk/lib/Checker/BugReporterVisitors.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/BugReporterVisitors.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/BugReporterVisitors.cpp (original)
+++ cfe/trunk/lib/Checker/BugReporterVisitors.cpp Tue Apr 20 19:45:42 2010
@@ -47,14 +47,6 @@
 }
 
 const Stmt*
-clang::bugreporter::GetReceiverExpr(const ExplodedNode *N){
-  const Stmt *S = N->getLocationAs<PostStmt>()->getStmt();
-  if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S))
-    return ME->getReceiver();
-  return NULL;
-}
-
-const Stmt*
 clang::bugreporter::GetDenomExpr(const ExplodedNode *N) {
   const Stmt *S = N->getLocationAs<PreStmt>()->getStmt();
   if (const BinaryOperator *BE = dyn_cast<BinaryOperator>(S))
@@ -402,7 +394,7 @@
     const ObjCMessageExpr *ME = P->getStmtAs<ObjCMessageExpr>();
     if (!ME)
       return 0;
-    const Expr *Receiver = ME->getReceiver();
+    const Expr *Receiver = ME->getInstanceReceiver();
     if (!Receiver)
       return 0;
     const GRState *state = N->getState();

Modified: cfe/trunk/lib/Checker/CFRefCount.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/CFRefCount.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/CFRefCount.cpp (original)
+++ cfe/trunk/lib/Checker/CFRefCount.cpp Tue Apr 20 19:45:42 2010
@@ -603,12 +603,33 @@
 
     Selector S = ME->getSelector();
 
-    if (Expr* Receiver = ME->getReceiver()) {
-      const ObjCInterfaceDecl* OD = getReceiverDecl(Receiver);
-      return OD ? M[ObjCSummaryKey(OD->getIdentifier(), S)] : M[S];
+    const ObjCInterfaceDecl* OD = 0;
+    bool IsInstanceMessage = false;
+    switch (ME->getReceiverKind()) {
+    case ObjCMessageExpr::Instance:
+      OD = getReceiverDecl(ME->getInstanceReceiver());
+      IsInstanceMessage = true;
+      break;
+
+    case ObjCMessageExpr::SuperInstance:
+      IsInstanceMessage = true;
+      OD = ME->getSuperType()->getAs<ObjCObjectPointerType>()
+                                                        ->getInterfaceDecl();
+      break;
+
+    case ObjCMessageExpr::Class:
+      OD = ME->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+      break;
+
+    case ObjCMessageExpr::SuperClass:
+      OD = ME->getSuperType()->getAs<ObjCInterfaceType>()->getDecl();
+      break;
     }
 
-    return M[ObjCSummaryKey(ME->getClassName(), S)];
+    if (IsInstanceMessage)
+      return OD ? M[ObjCSummaryKey(OD->getIdentifier(), S)] : M[S];
+
+    return M[ObjCSummaryKey(OD->getIdentifier(), S)];
   }
 
   RetainSummary*& operator[](ObjCSummaryKey K) {
@@ -836,7 +857,7 @@
   
   RetainSummary* getInstanceMethodSummary(const ObjCMessageExpr* ME,
                                           const ObjCInterfaceDecl* ID) {
-    return getInstanceMethodSummary(ME->getSelector(), ME->getClassName(),
+    return getInstanceMethodSummary(ME->getSelector(), 0,
                             ID, ME->getMethodDecl(), ME->getType());
   }
 
@@ -851,8 +872,21 @@
                                        QualType RetTy);
 
   RetainSummary *getClassMethodSummary(const ObjCMessageExpr *ME) {
-    return getClassMethodSummary(ME->getSelector(), ME->getClassName(),
-                                 ME->getClassInfo().Decl,
+    ObjCInterfaceDecl *Class = 0;
+    switch (ME->getReceiverKind()) {
+    case ObjCMessageExpr::Class:
+    case ObjCMessageExpr::SuperClass:
+      Class = ME->getReceiverInterface();
+      break;
+
+    case ObjCMessageExpr::Instance:
+    case ObjCMessageExpr::SuperInstance:
+      break;
+    }
+
+    return getClassMethodSummary(ME->getSelector(), 
+                                 Class? Class->getIdentifier() : 0,
+                                 Class,
                                  ME->getMethodDecl(), ME->getType());
   }
 
@@ -1333,37 +1367,44 @@
 
   // We need the type-information of the tracked receiver object
   // Retrieve it from the state.
-  const Expr *Receiver = ME->getReceiver();
+  const Expr *Receiver = ME->getInstanceReceiver();
   const ObjCInterfaceDecl* ID = 0;
 
   // FIXME: Is this really working as expected?  There are cases where
   //  we just use the 'ID' from the message expression.
-  SVal receiverV = state->getSValAsScalarOrLoc(Receiver);
+  SVal receiverV;
+
+  if (const Expr *Receiver = ME->getInstanceReceiver()) {
+    receiverV = state->getSValAsScalarOrLoc(Receiver);
   
-  // FIXME: Eventually replace the use of state->get<RefBindings> with
-  // a generic API for reasoning about the Objective-C types of symbolic
-  // objects.
-  if (SymbolRef Sym = receiverV.getAsLocSymbol())
-    if (const RefVal *T = state->get<RefBindings>(Sym))
-      if (const ObjCObjectPointerType* PT = 
+    // FIXME: Eventually replace the use of state->get<RefBindings> with
+    // a generic API for reasoning about the Objective-C types of symbolic
+    // objects.
+    if (SymbolRef Sym = receiverV.getAsLocSymbol())
+      if (const RefVal *T = state->get<RefBindings>(Sym))
+        if (const ObjCObjectPointerType* PT = 
             T->getType()->getAs<ObjCObjectPointerType>())
-        ID = PT->getInterfaceDecl();
+          ID = PT->getInterfaceDecl();
   
-  // FIXME: this is a hack.  This may or may not be the actual method
-  //  that is called.
-  if (!ID) {
-    if (const ObjCObjectPointerType *PT =
-        Receiver->getType()->getAs<ObjCObjectPointerType>())
-      ID = PT->getInterfaceDecl();
+    // FIXME: this is a hack.  This may or may not be the actual method
+    //  that is called.
+    if (!ID) {
+      if (const ObjCObjectPointerType *PT =
+          Receiver->getType()->getAs<ObjCObjectPointerType>())
+        ID = PT->getInterfaceDecl();
+    }
+  } else {
+    // FIXME: Hack for 'super'.
+    ID = ME->getReceiverInterface();
   }
-  
+
   // FIXME: The receiver could be a reference to a class, meaning that
   //  we should use the class method.
   RetainSummary *Summ = getInstanceMethodSummary(ME, ID);
   
   // Special-case: are we sending a mesage to "self"?
   //  This is a hack.  When we have full-IP this should be removed.
-  if (isa<ObjCMethodDecl>(LC->getDecl())) {
+  if (isa<ObjCMethodDecl>(LC->getDecl()) && Receiver) {
     if (const loc::MemRegionVal *L = dyn_cast<loc::MemRegionVal>(&receiverV)) {
       // Get the region associated with 'self'.
       if (const ImplicitParamDecl *SelfDecl = LC->getSelfDecl()) {
@@ -2144,7 +2185,7 @@
       }
     }
     else if (const ObjCMessageExpr *ME = dyn_cast<ObjCMessageExpr>(S)) {
-      if (const Expr *receiver = ME->getReceiver())
+      if (const Expr *receiver = ME->getInstanceReceiver())
         if (CurrSt->getSValAsScalarOrLoc(receiver).getAsLocSymbol() == Sym) {
           // The symbol we are tracking is the receiver.
           AEffects.push_back(Summ->getReceiverEffect());
@@ -2510,7 +2551,7 @@
         // id, id<...>, or Class. If we have an ObjCInterfaceDecl, we know this
         // is a call to a class method whose type we can resolve.  In such
         // cases, promote the return type to XXX* (where XXX is the class).
-        const ObjCInterfaceDecl *D = ME->getClassInfo().Decl;
+        const ObjCInterfaceDecl *D = ME->getReceiverInterface();
         return !D ? RetTy : Ctx.getPointerType(Ctx.getObjCInterfaceType(D));
       }
 
@@ -2660,15 +2701,15 @@
   RetEffect RE = Summ.getRetEffect();
 
   if (RE.getKind() == RetEffect::OwnedWhenTrackedReceiver) {
-    assert(Receiver);
-    SVal V = state->getSValAsScalarOrLoc(Receiver);
     bool found = false;
-    if (SymbolRef Sym = V.getAsLocSymbol())
-      if (state->get<RefBindings>(Sym)) {
-        found = true;
-        RE = Summaries.getObjAllocRetEffect();
-      }
-
+    if (Receiver) {
+      SVal V = state->getSValAsScalarOrLoc(Receiver);
+      if (SymbolRef Sym = V.getAsLocSymbol())
+        if (state->get<RefBindings>(Sym)) {
+          found = true;
+          RE = Summaries.getObjAllocRetEffect();
+        }
+    } // FIXME: Otherwise, this is a send-to-super instance message.
     if (!found)
       RE = RetEffect::MakeNoRet();
   }
@@ -2802,12 +2843,12 @@
                                      ExplodedNode* Pred,
                                      const GRState *state) {
   RetainSummary *Summ =
-    ME->getReceiver()
+    ME->isInstanceMessage()
       ? Summaries.getInstanceMethodSummary(ME, state,Pred->getLocationContext())
       : Summaries.getClassMethodSummary(ME);
 
   assert(Summ && "RetainSummary is null");
-  EvalSummary(Dst, Eng, Builder, ME, ME->getReceiver(), *Summ, NULL,
+  EvalSummary(Dst, Eng, Builder, ME, ME->getInstanceReceiver(), *Summ, NULL,
               ME->arg_begin(), ME->arg_end(), Pred, state);
 }
 

Modified: cfe/trunk/lib/Checker/CallAndMessageChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/CallAndMessageChecker.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/CallAndMessageChecker.cpp (original)
+++ cfe/trunk/lib/Checker/CallAndMessageChecker.cpp Tue Apr 20 19:45:42 2010
@@ -218,7 +218,8 @@
 
   const GRState *state = C.getState();
 
-  if (const Expr *receiver = ME->getReceiver())
+  // FIXME: Handle 'super'?
+  if (const Expr *receiver = ME->getInstanceReceiver())
     if (state->getSVal(receiver).isUndef()) {
       if (ExplodedNode *N = C.GenerateSink()) {
         if (!BT_msg_undef)
@@ -265,10 +266,11 @@
      << ME->getType().getAsString() << "' that will be garbage";
 
   EnhancedBugReport *report = new EnhancedBugReport(*BT_msg_ret, os.str(), N);
-  const Expr *receiver = ME->getReceiver();
-  report->addRange(receiver->getSourceRange());
-  report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
-                            receiver);
+  if (const Expr *receiver = ME->getInstanceReceiver()) {
+    report->addRange(receiver->getSourceRange());
+    report->addVisitorCreator(bugreporter::registerTrackNullOrUndefValue,
+                              receiver);
+  }
   C.EmitReport(report);
 }
 

Modified: cfe/trunk/lib/Checker/CheckObjCDealloc.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/CheckObjCDealloc.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/CheckObjCDealloc.cpp (original)
+++ cfe/trunk/lib/Checker/CheckObjCDealloc.cpp Tue Apr 20 19:45:42 2010
@@ -27,10 +27,14 @@
 static bool scan_dealloc(Stmt* S, Selector Dealloc) {
 
   if (ObjCMessageExpr* ME = dyn_cast<ObjCMessageExpr>(S))
-    if (ME->getSelector() == Dealloc)
-      if (ME->getReceiver())
-        if (Expr* Receiver = ME->getReceiver()->IgnoreParenCasts())
-          return isa<ObjCSuperExpr>(Receiver);
+    if (ME->getSelector() == Dealloc) {
+      switch (ME->getReceiverKind()) {
+      case ObjCMessageExpr::Instance: return false;
+      case ObjCMessageExpr::SuperInstance: return true;
+      case ObjCMessageExpr::Class: break;
+      case ObjCMessageExpr::SuperClass: break;
+      }
+    }
 
   // Recurse to children.
 
@@ -50,16 +54,16 @@
   // [mMyIvar release]
   if (ObjCMessageExpr* ME = dyn_cast<ObjCMessageExpr>(S))
     if (ME->getSelector() == Release)
-      if (ME->getReceiver())
-        if (Expr* Receiver = ME->getReceiver()->IgnoreParenCasts())
+      if (ME->getInstanceReceiver())
+        if (Expr* Receiver = ME->getInstanceReceiver()->IgnoreParenCasts())
           if (ObjCIvarRefExpr* E = dyn_cast<ObjCIvarRefExpr>(Receiver))
             if (E->getDecl() == ID)
               return true;
 
   // [self setMyIvar:nil];
   if (ObjCMessageExpr* ME = dyn_cast<ObjCMessageExpr>(S))
-    if (ME->getReceiver())
-      if (Expr* Receiver = ME->getReceiver()->IgnoreParenCasts())
+    if (ME->getInstanceReceiver())
+      if (Expr* Receiver = ME->getInstanceReceiver()->IgnoreParenCasts())
         if (DeclRefExpr* E = dyn_cast<DeclRefExpr>(Receiver))
           if (E->getDecl()->getIdentifier() == SelfII)
             if (ME->getMethodDecl() == PD->getSetterMethodDecl() &&

Modified: cfe/trunk/lib/Checker/GRExprEngine.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/GRExprEngine.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/GRExprEngine.cpp (original)
+++ cfe/trunk/lib/Checker/GRExprEngine.cpp Tue Apr 20 19:45:42 2010
@@ -2124,7 +2124,7 @@
 
   // But first evaluate the receiver (if any).
   ObjCMessageExpr::arg_iterator AI = ME->arg_begin(), AE = ME->arg_end();
-  if (Expr *Receiver = ME->getReceiver()) {
+  if (Expr *Receiver = ME->getInstanceReceiver()) {
     ExplodedNodeSet Tmp;
     Visit(Receiver, Pred, Tmp);
 
@@ -2176,7 +2176,7 @@
     SaveAndRestore<bool> OldSink(Builder->BuildSinks);
     SaveOr OldHasGen(Builder->HasGeneratedNode);
 
-    if (const Expr *Receiver = ME->getReceiver()) {
+    if (const Expr *Receiver = ME->getInstanceReceiver()) {
       const GRState *state = GetState(Pred);
 
       // Bifurcate the state into nil and non-nil ones.
@@ -2206,8 +2206,8 @@
       // Dispatch to plug-in transfer function.
       EvalObjCMessageExpr(DstEval, ME, Pred, notNilState);
     }
-    else {
-      IdentifierInfo* ClsName = ME->getClassName();
+    else if (ObjCInterfaceDecl *Iface = ME->getReceiverInterface()) {
+      IdentifierInfo* ClsName = Iface->getIdentifier();
       Selector S = ME->getSelector();
 
       // Check for special instance methods.

Modified: cfe/trunk/lib/Checker/NSAutoreleasePoolChecker.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Checker/NSAutoreleasePoolChecker.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/Checker/NSAutoreleasePoolChecker.cpp (original)
+++ cfe/trunk/lib/Checker/NSAutoreleasePoolChecker.cpp Tue Apr 20 19:45:42 2010
@@ -56,7 +56,7 @@
 NSAutoreleasePoolChecker::PreVisitObjCMessageExpr(CheckerContext &C,
                                                   const ObjCMessageExpr *ME) {
   
-  const Expr *receiver = ME->getReceiver();
+  const Expr *receiver = ME->getInstanceReceiver();
   if (!receiver)
     return;
   

Modified: cfe/trunk/lib/CodeGen/CGObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGObjC.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGObjC.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGObjC.cpp Tue Apr 20 19:45:42 2010
@@ -53,31 +53,34 @@
   // arguments in generic code.
 
   CGObjCRuntime &Runtime = CGM.getObjCRuntime();
-  const Expr *ReceiverExpr = E->getReceiver();
   bool isSuperMessage = false;
   bool isClassMessage = false;
   // Find the receiver
   llvm::Value *Receiver;
-  if (!ReceiverExpr) {
-    const ObjCInterfaceDecl *OID = E->getClassInfo().Decl;
-
-    // Very special case, super send in class method. The receiver is
-    // self (the class object) and the send uses super semantics.
-    if (!OID) {
-      assert(E->getClassName()->isStr("super") &&
-             "Unexpected missing class interface in message send.");
-      isSuperMessage = true;
-      Receiver = LoadObjCSelf();
-    } else {
-      Receiver = Runtime.GetClass(Builder, OID);
-    }
-
+  switch (E->getReceiverKind()) {
+  case ObjCMessageExpr::Instance:
+    Receiver = EmitScalarExpr(E->getInstanceReceiver());
+    break;
+
+  case ObjCMessageExpr::Class: {
+    const ObjCInterfaceType *IFace
+      = E->getClassReceiver()->getAs<ObjCInterfaceType>();
+    assert(IFace && "Invalid Objective-C class message send");
+    Receiver = Runtime.GetClass(Builder, IFace->getDecl());
     isClassMessage = true;
-  } else if (isa<ObjCSuperExpr>(E->getReceiver())) {
+    break;
+  }
+
+  case ObjCMessageExpr::SuperInstance:
+    Receiver = LoadObjCSelf();
     isSuperMessage = true;
+    break;
+
+  case ObjCMessageExpr::SuperClass:
     Receiver = LoadObjCSelf();
-  } else {
-    Receiver = EmitScalarExpr(E->getReceiver());
+    isSuperMessage = true;
+    isClassMessage = true;
+    break;
   }
 
   CallArgList Args;

Modified: cfe/trunk/lib/Frontend/PCHReaderStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHReaderStmt.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHReaderStmt.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHReaderStmt.cpp Tue Apr 20 19:45:42 2010
@@ -782,25 +782,42 @@
 
 unsigned PCHStmtReader::VisitObjCMessageExpr(ObjCMessageExpr *E) {
   VisitExpr(E);
-  E->setNumArgs(Record[Idx++]);
-  E->setLeftLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
-  E->setRightLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
-  E->setSelector(Reader.GetSelector(Record, Idx));
-  E->setMethodDecl(cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
-
-  E->setReceiver(
+  assert(Record[Idx] == E->getNumArgs());
+  ++Idx;
+  ObjCMessageExpr::ReceiverKind Kind
+    = static_cast<ObjCMessageExpr::ReceiverKind>(Record[Idx++]);
+  switch (Kind) {
+  case ObjCMessageExpr::Instance:
+    E->setInstanceReceiver(
          cast_or_null<Expr>(StmtStack[StmtStack.size() - E->getNumArgs() - 1]));
-  if (!E->getReceiver()) {
-    ObjCMessageExpr::ClassInfo CI;
-    CI.Decl = cast_or_null<ObjCInterfaceDecl>(Reader.GetDecl(Record[Idx++]));
-    CI.Name = Reader.GetIdentifierInfo(Record, Idx);
-    CI.Loc = SourceLocation::getFromRawEncoding(Record[Idx++]);
-    E->setClassInfo(CI);
+    break;
+
+  case ObjCMessageExpr::Class:
+    E->setClassReceiver(Reader.GetTypeSourceInfo(Record, Idx));
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+  case ObjCMessageExpr::SuperInstance: {
+    QualType T = Reader.GetType(Record[Idx++]);
+    SourceLocation SuperLoc = SourceLocation::getFromRawEncoding(Record[Idx++]);
+    E->setSuper(SuperLoc, T, Kind == ObjCMessageExpr::SuperInstance);
+    break;
+  }
   }
 
+  assert(Kind == E->getReceiverKind());
+
+  if (Record[Idx++])
+    E->setMethodDecl(cast_or_null<ObjCMethodDecl>(Reader.GetDecl(Record[Idx++])));
+  else
+    E->setSelector(Reader.GetSelector(Record, Idx));
+
+  E->setLeftLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+  E->setRightLoc(SourceLocation::getFromRawEncoding(Record[Idx++]));
+
   for (unsigned I = 0, N = E->getNumArgs(); I != N; ++I)
     E->setArg(I, cast<Expr>(StmtStack[StmtStack.size() - N + I]));
-  return E->getNumArgs() + 1;
+  return E->getNumArgs() + (Kind == ObjCMessageExpr::Instance);
 }
 
 unsigned PCHStmtReader::VisitObjCSuperExpr(ObjCSuperExpr *E) {
@@ -1195,7 +1212,8 @@
       S = new (Context) ObjCImplicitSetterGetterRefExpr(Empty);
       break;
     case pch::EXPR_OBJC_MESSAGE_EXPR:
-      S = new (Context) ObjCMessageExpr(Empty);
+      S = ObjCMessageExpr::CreateEmpty(*Context,
+                                     Record[PCHStmtReader::NumExprFields]);
       break;
     case pch::EXPR_OBJC_SUPER_EXPR:
       S = new (Context) ObjCSuperExpr(Empty);

Modified: cfe/trunk/lib/Frontend/PCHWriterStmt.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/PCHWriterStmt.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/PCHWriterStmt.cpp (original)
+++ cfe/trunk/lib/Frontend/PCHWriterStmt.cpp Tue Apr 20 19:45:42 2010
@@ -712,18 +712,33 @@
 void PCHStmtWriter::VisitObjCMessageExpr(ObjCMessageExpr *E) {
   VisitExpr(E);
   Record.push_back(E->getNumArgs());
+  Record.push_back((unsigned)E->getReceiverKind()); // FIXME: stable encoding
+  switch (E->getReceiverKind()) {
+  case ObjCMessageExpr::Instance:
+    Writer.WriteSubStmt(E->getInstanceReceiver());
+    break;
+
+  case ObjCMessageExpr::Class:
+    Writer.AddTypeSourceInfo(E->getClassReceiverTypeInfo(), Record);
+    break;
+
+  case ObjCMessageExpr::SuperClass:
+  case ObjCMessageExpr::SuperInstance:
+    Writer.AddTypeRef(E->getSuperType(), Record);
+    Writer.AddSourceLocation(E->getSuperLoc(), Record);
+    break;
+  }
+
+  if (E->getMethodDecl()) {
+    Record.push_back(1);
+    Writer.AddDeclRef(E->getMethodDecl(), Record);
+  } else {
+    Record.push_back(0);
+    Writer.AddSelectorRef(E->getSelector(), Record);    
+  }
+    
   Writer.AddSourceLocation(E->getLeftLoc(), Record);
   Writer.AddSourceLocation(E->getRightLoc(), Record);
-  Writer.AddSelectorRef(E->getSelector(), Record);
-  Writer.AddDeclRef(E->getMethodDecl(), Record); // optional
-  Writer.WriteSubStmt(E->getReceiver());
-
-  if (!E->getReceiver()) {
-    ObjCMessageExpr::ClassInfo CI = E->getClassInfo();
-    Writer.AddDeclRef(CI.Decl, Record);
-    Writer.AddIdentifierRef(CI.Name, Record);
-    Writer.AddSourceLocation(CI.Loc, Record);
-  }
 
   for (CallExpr::arg_iterator Arg = E->arg_begin(), ArgEnd = E->arg_end();
        Arg != ArgEnd; ++Arg)

Modified: cfe/trunk/lib/Frontend/RewriteObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Frontend/RewriteObjC.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/Frontend/RewriteObjC.cpp (original)
+++ cfe/trunk/lib/Frontend/RewriteObjC.cpp Tue Apr 20 19:45:42 2010
@@ -1239,11 +1239,26 @@
     // This allows us to handle chain/nested property getters.
     Receiver = PropGetters[PRE];
   }
-  MsgExpr = new (Context) ObjCMessageExpr(*Context, dyn_cast<Expr>(Receiver),
-                                PDecl->getSetterName(), PDecl->getType(),
-                                PDecl->getSetterMethodDecl(),
-                                SourceLocation(), SourceLocation(),
-                                &ExprVec[0], 1);
+  if (isa<ObjCSuperExpr>(Receiver))
+    MsgExpr = ObjCMessageExpr::Create(*Context, 
+                                      PDecl->getType().getNonReferenceType(),
+                                      /*FIXME?*/SourceLocation(),
+                                      Receiver->getLocStart(),
+                                      /*IsInstanceSuper=*/true,
+                                      cast<Expr>(Receiver)->getType(),
+                                      PDecl->getSetterName(),
+                                      PDecl->getSetterMethodDecl(),
+                                      &ExprVec[0], 1,
+                                      /*FIXME:*/SourceLocation());
+  else
+    MsgExpr = ObjCMessageExpr::Create(*Context, 
+                                      PDecl->getType().getNonReferenceType(),
+                                      /*FIXME: */SourceLocation(),
+                                      cast<Expr>(Receiver),
+                                      PDecl->getSetterName(),
+                                      PDecl->getSetterMethodDecl(),
+                                      &ExprVec[0], 1,
+                                      /*FIXME:*/SourceLocation());
   Stmt *ReplacingStmt = SynthMessageExpr(MsgExpr);
 
   // Now do the actual rewrite.
@@ -1268,11 +1283,27 @@
     // This allows us to handle chain/nested property getters.
     Receiver = PropGetters[PRE];
   }
-  MsgExpr = new (Context) ObjCMessageExpr(*Context, dyn_cast<Expr>(Receiver),
-                                PDecl->getGetterName(), PDecl->getType(),
-                                PDecl->getGetterMethodDecl(),
-                                SourceLocation(), SourceLocation(),
-                                0, 0);
+
+  if (isa<ObjCSuperExpr>(Receiver))
+    MsgExpr = ObjCMessageExpr::Create(*Context, 
+                                      PDecl->getType().getNonReferenceType(),
+                                      /*FIXME:*/SourceLocation(),
+                                      Receiver->getLocStart(),
+                                      /*IsInstanceSuper=*/true,
+                                      cast<Expr>(Receiver)->getType(),
+                                      PDecl->getGetterName(), 
+                                      PDecl->getGetterMethodDecl(),
+                                      0, 0, 
+                                      /*FIXME:*/SourceLocation());
+  else
+    MsgExpr = ObjCMessageExpr::Create(*Context, 
+                                      PDecl->getType().getNonReferenceType(),
+                                      /*FIXME:*/SourceLocation(),
+                                      cast<Expr>(Receiver),
+                                      PDecl->getGetterName(), 
+                                      PDecl->getGetterMethodDecl(),
+                                      0, 0, 
+                                      /*FIXME:*/SourceLocation());
 
   Stmt *ReplacingStmt = SynthMessageExpr(MsgExpr);
 
@@ -2687,205 +2718,211 @@
 
   // Synthesize a call to objc_msgSend().
   llvm::SmallVector<Expr*, 8> MsgExprs;
-  IdentifierInfo *clsName = Exp->getClassName();
-
-  // Derive/push the receiver/selector, 2 implicit arguments to objc_msgSend().
-  if (clsName) { // class message.
-    // FIXME: We need to fix Sema (and the AST for ObjCMessageExpr) to handle
-    // the 'super' idiom within a class method.
-    if (clsName->getName() == "super") {
-      MsgSendFlavor = MsgSendSuperFunctionDecl;
-      if (MsgSendStretFlavor)
-        MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
-      assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
-
-      ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
-
-      llvm::SmallVector<Expr*, 4> InitExprs;
-
-      // set the receiver to self, the first argument to all methods.
-      InitExprs.push_back(
-        NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                                 CastExpr::CK_Unknown,
-                     new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
-                                     Context->getObjCIdType(),
-                                     SourceLocation()))
-                          ); // set the 'receiver'.
-
-      // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
-      llvm::SmallVector<Expr*, 8> ClsExprs;
-      QualType argType = Context->getPointerType(Context->CharTy);
-      ClsExprs.push_back(StringLiteral::Create(*Context,
-                                     ClassDecl->getIdentifier()->getNameStart(),
-                                     ClassDecl->getIdentifier()->getLength(),
-                                     false, argType, SourceLocation()));
-      CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
-                                                   &ClsExprs[0],
-                                                   ClsExprs.size(),
-                                                   StartLoc,
-                                                   EndLoc);
-      // (Class)objc_getClass("CurrentClass")
-      CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
-                                               Context->getObjCClassType(),
-                                               CastExpr::CK_Unknown, Cls);
-      ClsExprs.clear();
-      ClsExprs.push_back(ArgExpr);
-      Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
-                                         &ClsExprs[0], ClsExprs.size(),
-                                         StartLoc, EndLoc);
-      
-      // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
-      // To turn off a warning, type-cast to 'id'
-      InitExprs.push_back( // set 'super class', using class_getSuperclass().
-                          NoTypeInfoCStyleCastExpr(Context,
-                                                   Context->getObjCIdType(),
-                                                   CastExpr::CK_Unknown, Cls));
-      // struct objc_super
-      QualType superType = getSuperStructType();
-      Expr *SuperRep;
-
-      if (LangOpts.Microsoft) {
-        SynthSuperContructorFunctionDecl();
-        // Simulate a contructor call...
-        DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
-                                           superType, SourceLocation());
-        SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
-                                          InitExprs.size(),
-                                          superType, SourceLocation());
-        // The code for super is a little tricky to prevent collision with
-        // the structure definition in the header. The rewriter has it's own
-        // internal definition (__rw_objc_super) that is uses. This is why
-        // we need the cast below. For example:
-        // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
-        //
-        SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
-                                 Context->getPointerType(SuperRep->getType()),
-                                 SourceLocation());
-        SuperRep = NoTypeInfoCStyleCastExpr(Context,
-                                            Context->getPointerType(superType),
-                                            CastExpr::CK_Unknown, SuperRep);
-      } else {
-        // (struct objc_super) { <exprs from above> }
-        InitListExpr *ILE =
-          new (Context) InitListExpr(*Context, SourceLocation(),
-                                     &InitExprs[0], InitExprs.size(),
-                                     SourceLocation());
-        TypeSourceInfo *superTInfo
-          = Context->getTrivialTypeSourceInfo(superType);
-        SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
-                                                     superType, ILE, false);
-        // struct objc_super *
-        SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
-                                 Context->getPointerType(SuperRep->getType()),
-                                 SourceLocation());
-      }
-      MsgExprs.push_back(SuperRep);
+  switch (Exp->getReceiverKind()) {
+  case ObjCMessageExpr::SuperClass: {
+    MsgSendFlavor = MsgSendSuperFunctionDecl;
+    if (MsgSendStretFlavor)
+      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+
+    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+
+    llvm::SmallVector<Expr*, 4> InitExprs;
+
+    // set the receiver to self, the first argument to all methods.
+    InitExprs.push_back(
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CastExpr::CK_Unknown,
+                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                                   Context->getObjCIdType(),
+                                   SourceLocation()))
+                        ); // set the 'receiver'.
+
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    llvm::SmallVector<Expr*, 8> ClsExprs;
+    QualType argType = Context->getPointerType(Context->CharTy);
+    ClsExprs.push_back(StringLiteral::Create(*Context,
+                                   ClassDecl->getIdentifier()->getNameStart(),
+                                   ClassDecl->getIdentifier()->getLength(),
+                                   false, argType, SourceLocation()));
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetMetaClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(),
+                                                 StartLoc,
+                                                 EndLoc);
+    // (Class)objc_getClass("CurrentClass")
+    CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
+                                             Context->getObjCClassType(),
+                                             CastExpr::CK_Unknown, Cls);
+    ClsExprs.clear();
+    ClsExprs.push_back(ArgExpr);
+    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+                                       &ClsExprs[0], ClsExprs.size(),
+                                       StartLoc, EndLoc);
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    // To turn off a warning, type-cast to 'id'
+    InitExprs.push_back( // set 'super class', using class_getSuperclass().
+                        NoTypeInfoCStyleCastExpr(Context,
+                                                 Context->getObjCIdType(),
+                                                 CastExpr::CK_Unknown, Cls));
+    // struct objc_super
+    QualType superType = getSuperStructType();
+    Expr *SuperRep;
+
+    if (LangOpts.Microsoft) {
+      SynthSuperContructorFunctionDecl();
+      // Simulate a contructor call...
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
+                                         superType, SourceLocation());
+      SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
+                                        InitExprs.size(),
+                                        superType, SourceLocation());
+      // The code for super is a little tricky to prevent collision with
+      // the structure definition in the header. The rewriter has it's own
+      // internal definition (__rw_objc_super) that is uses. This is why
+      // we need the cast below. For example:
+      // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+      //
+      SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                               SourceLocation());
+      SuperRep = NoTypeInfoCStyleCastExpr(Context,
+                                          Context->getPointerType(superType),
+                                          CastExpr::CK_Unknown, SuperRep);
     } else {
-      llvm::SmallVector<Expr*, 8> ClsExprs;
-      QualType argType = Context->getPointerType(Context->CharTy);
-      ClsExprs.push_back(StringLiteral::Create(*Context,
-                                               clsName->getNameStart(),
-                                               clsName->getLength(),
-                                               false, argType,
-                                               SourceLocation()));
-      CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
-                                                   &ClsExprs[0],
-                                                   ClsExprs.size(), 
-                                                   StartLoc, EndLoc);
-      MsgExprs.push_back(Cls);
-    }
-  } else { // instance message.
-    Expr *recExpr = Exp->getReceiver();
-
-    if (isSuperReceiver(recExpr)) {
-      MsgSendFlavor = MsgSendSuperFunctionDecl;
-      if (MsgSendStretFlavor)
-        MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
-      assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
-      ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
-      llvm::SmallVector<Expr*, 4> InitExprs;
-
-      InitExprs.push_back(
-        NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                                 CastExpr::CK_Unknown,
-                     new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
-                                     Context->getObjCIdType(),
-                                     SourceLocation()))
-                          ); // set the 'receiver'.
-      
-      // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
-      llvm::SmallVector<Expr*, 8> ClsExprs;
-      QualType argType = Context->getPointerType(Context->CharTy);
-      ClsExprs.push_back(StringLiteral::Create(*Context,
-                                     ClassDecl->getIdentifier()->getNameStart(),
-                                     ClassDecl->getIdentifier()->getLength(),
-                                     false, argType, SourceLocation()));
-      CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
-                                                   &ClsExprs[0],
-                                                   ClsExprs.size(), 
-                                                   StartLoc, EndLoc);
-      // (Class)objc_getClass("CurrentClass")
-      CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
-                                                   Context->getObjCClassType(),
-                                                   CastExpr::CK_Unknown, Cls);
-      ClsExprs.clear();
-      ClsExprs.push_back(ArgExpr);
-      Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
-                                         &ClsExprs[0], ClsExprs.size(),
-                                         StartLoc, EndLoc);
-      
-      // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
-      // To turn off a warning, type-cast to 'id'
-      InitExprs.push_back(
-        // set 'super class', using class_getSuperclass().
-        NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                                 CastExpr::CK_Unknown, Cls));
-      // struct objc_super
-      QualType superType = getSuperStructType();
-      Expr *SuperRep;
-
-      if (LangOpts.Microsoft) {
-        SynthSuperContructorFunctionDecl();
-        // Simulate a contructor call...
-        DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
-                                           superType, SourceLocation());
-        SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
-                                          InitExprs.size(),
-                                          superType, SourceLocation());
-        // The code for super is a little tricky to prevent collision with
-        // the structure definition in the header. The rewriter has it's own
-        // internal definition (__rw_objc_super) that is uses. This is why
-        // we need the cast below. For example:
-        // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
-        //
-        SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
-                                 Context->getPointerType(SuperRep->getType()),
-                                 SourceLocation());
-        SuperRep = NoTypeInfoCStyleCastExpr(Context,
-                                 Context->getPointerType(superType),
-                                 CastExpr::CK_Unknown, SuperRep);
-      } else {
-        // (struct objc_super) { <exprs from above> }
-        InitListExpr *ILE =
-          new (Context) InitListExpr(*Context, SourceLocation(),
-                                     &InitExprs[0], InitExprs.size(),
-                                     SourceLocation());
-        TypeSourceInfo *superTInfo
-          = Context->getTrivialTypeSourceInfo(superType);
-        SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
-                                                     superType, ILE, false);
-      }
-      MsgExprs.push_back(SuperRep);
+      // (struct objc_super) { <exprs from above> }
+      InitListExpr *ILE =
+        new (Context) InitListExpr(*Context, SourceLocation(),
+                                   &InitExprs[0], InitExprs.size(),
+                                   SourceLocation());
+      TypeSourceInfo *superTInfo
+        = Context->getTrivialTypeSourceInfo(superType);
+      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+                                                   superType, ILE, false);
+      // struct objc_super *
+      SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                               SourceLocation());
+    }
+    MsgExprs.push_back(SuperRep);
+    break;
+  }
+
+  case ObjCMessageExpr::Class: {
+    llvm::SmallVector<Expr*, 8> ClsExprs;
+    QualType argType = Context->getPointerType(Context->CharTy);
+    ObjCInterfaceDecl *Class
+      = Exp->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+    IdentifierInfo *clsName = Class->getIdentifier();
+    ClsExprs.push_back(StringLiteral::Create(*Context,
+                                             clsName->getNameStart(),
+                                             clsName->getLength(),
+                                             false, argType,
+                                             SourceLocation()));
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(), 
+                                                 StartLoc, EndLoc);
+    MsgExprs.push_back(Cls);
+    break;
+  }
+
+  case ObjCMessageExpr::SuperInstance:{
+    MsgSendFlavor = MsgSendSuperFunctionDecl;
+    if (MsgSendStretFlavor)
+      MsgSendStretFlavor = MsgSendSuperStretFunctionDecl;
+    assert(MsgSendFlavor && "MsgSendFlavor is NULL!");
+    ObjCInterfaceDecl *ClassDecl = CurMethodDef->getClassInterface();
+    llvm::SmallVector<Expr*, 4> InitExprs;
+
+    InitExprs.push_back(
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CastExpr::CK_Unknown,
+                   new (Context) DeclRefExpr(CurMethodDef->getSelfDecl(),
+                                   Context->getObjCIdType(),
+                                   SourceLocation()))
+                        ); // set the 'receiver'.
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    llvm::SmallVector<Expr*, 8> ClsExprs;
+    QualType argType = Context->getPointerType(Context->CharTy);
+    ClsExprs.push_back(StringLiteral::Create(*Context,
+                                   ClassDecl->getIdentifier()->getNameStart(),
+                                   ClassDecl->getIdentifier()->getLength(),
+                                   false, argType, SourceLocation()));
+    CallExpr *Cls = SynthesizeCallToFunctionDecl(GetClassFunctionDecl,
+                                                 &ClsExprs[0],
+                                                 ClsExprs.size(), 
+                                                 StartLoc, EndLoc);
+    // (Class)objc_getClass("CurrentClass")
+    CastExpr *ArgExpr = NoTypeInfoCStyleCastExpr(Context,
+                                                 Context->getObjCClassType(),
+                                                 CastExpr::CK_Unknown, Cls);
+    ClsExprs.clear();
+    ClsExprs.push_back(ArgExpr);
+    Cls = SynthesizeCallToFunctionDecl(GetSuperClassFunctionDecl,
+                                       &ClsExprs[0], ClsExprs.size(),
+                                       StartLoc, EndLoc);
+    
+    // (id)class_getSuperclass((Class)objc_getClass("CurrentClass"))
+    // To turn off a warning, type-cast to 'id'
+    InitExprs.push_back(
+      // set 'super class', using class_getSuperclass().
+      NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                               CastExpr::CK_Unknown, Cls));
+    // struct objc_super
+    QualType superType = getSuperStructType();
+    Expr *SuperRep;
+
+    if (LangOpts.Microsoft) {
+      SynthSuperContructorFunctionDecl();
+      // Simulate a contructor call...
+      DeclRefExpr *DRE = new (Context) DeclRefExpr(SuperContructorFunctionDecl,
+                                         superType, SourceLocation());
+      SuperRep = new (Context) CallExpr(*Context, DRE, &InitExprs[0],
+                                        InitExprs.size(),
+                                        superType, SourceLocation());
+      // The code for super is a little tricky to prevent collision with
+      // the structure definition in the header. The rewriter has it's own
+      // internal definition (__rw_objc_super) that is uses. This is why
+      // we need the cast below. For example:
+      // (struct objc_super *)&__rw_objc_super((id)self, (id)objc_getClass("SUPER"))
+      //
+      SuperRep = new (Context) UnaryOperator(SuperRep, UnaryOperator::AddrOf,
+                               Context->getPointerType(SuperRep->getType()),
+                               SourceLocation());
+      SuperRep = NoTypeInfoCStyleCastExpr(Context,
+                               Context->getPointerType(superType),
+                               CastExpr::CK_Unknown, SuperRep);
     } else {
-      // Remove all type-casts because it may contain objc-style types; e.g.
-      // Foo<Proto> *.
-      while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
-        recExpr = CE->getSubExpr();
-      recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
-                                         CastExpr::CK_Unknown, recExpr);
-      MsgExprs.push_back(recExpr);
-    }
+      // (struct objc_super) { <exprs from above> }
+      InitListExpr *ILE =
+        new (Context) InitListExpr(*Context, SourceLocation(),
+                                   &InitExprs[0], InitExprs.size(),
+                                   SourceLocation());
+      TypeSourceInfo *superTInfo
+        = Context->getTrivialTypeSourceInfo(superType);
+      SuperRep = new (Context) CompoundLiteralExpr(SourceLocation(), superTInfo,
+                                                   superType, ILE, false);
+    }
+    MsgExprs.push_back(SuperRep);
+    break;
+  }
+
+  case ObjCMessageExpr::Instance: {
+    // Remove all type-casts because it may contain objc-style types; e.g.
+    // Foo<Proto> *.
+    Expr *recExpr = Exp->getInstanceReceiver();
+    while (CStyleCastExpr *CE = dyn_cast<CStyleCastExpr>(recExpr))
+      recExpr = CE->getSubExpr();
+    recExpr = NoTypeInfoCStyleCastExpr(Context, Context->getObjCIdType(),
+                                       CastExpr::CK_Unknown, recExpr);
+    MsgExprs.push_back(recExpr);
+    break;
+  }
   }
+
   // Create a call to sel_registerName("selName"), it will be the 2nd argument.
   llvm::SmallVector<Expr*, 8> SelExprs;
   QualType argType = Context->getPointerType(Context->CharTy);

Modified: cfe/trunk/lib/Index/Analyzer.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Index/Analyzer.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/Index/Analyzer.cpp (original)
+++ cfe/trunk/lib/Index/Analyzer.cpp Tue Apr 20 19:45:42 2010
@@ -153,9 +153,10 @@
     ObjCInterfaceDecl *MsgD = 0;
     ObjCMessageExpr *Msg = cast<ObjCMessageExpr>(ASTLoc.AsStmt());
 
-    if (Msg->getReceiver()) {
+    switch (Msg->getReceiverKind()) {
+    case ObjCMessageExpr::Instance: {
       const ObjCObjectPointerType *OPT =
-          Msg->getReceiver()->getType()->getAsObjCInterfacePointerType();
+          Msg->getInstanceReceiver()->getType()->getAsObjCInterfacePointerType();
 
       // Can be anything! Accept it as a possibility..
       if (!OPT || OPT->isObjCIdType() || OPT->isObjCQualifiedIdType())
@@ -171,15 +172,34 @@
       // Should be an instance method.
       if (!IsInstanceMethod)
         return false;
+      break;
+    }
 
-    } else {
+    case ObjCMessageExpr::Class: {
       // Expecting class method.
       if (IsInstanceMethod)
         return false;
 
-      MsgD = Msg->getClassInfo().Decl;
-      // FIXME: Case when we only have an identifier.
-      assert(MsgD && "Identifier only");
+      MsgD = Msg->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+      break;
+    }
+
+    case ObjCMessageExpr::SuperClass:
+      // Expecting class method.
+      if (IsInstanceMethod)
+        return false;
+
+      MsgD = Msg->getSuperType()->getAs<ObjCInterfaceType>()->getDecl();
+      break;
+
+    case ObjCMessageExpr::SuperInstance:
+      // Expecting instance method.
+      if (!IsInstanceMethod)
+        return false;
+
+      MsgD = Msg->getSuperType()->getAs<ObjCObjectPointerType>()
+                                                          ->getInterfaceDecl();
+      break;
     }
 
     assert(MsgD);
@@ -248,31 +268,44 @@
     ObjCInterfaceDecl *MsgD = 0;
 
     while (true) {
-      if (Msg->getReceiver() == 0) {
-        CanBeClassMethod = true;
-        MsgD = Msg->getClassInfo().Decl;
-        // FIXME: Case when we only have an identifier.
-        assert(MsgD && "Identifier only");
-        break;
-      }
+      switch (Msg->getReceiverKind()) {
+      case ObjCMessageExpr::Instance: {
+        const ObjCObjectPointerType *OPT =
+          Msg->getInstanceReceiver()->getType()
+                                      ->getAsObjCInterfacePointerType();
 
-      const ObjCObjectPointerType *OPT =
-          Msg->getReceiver()->getType()->getAsObjCInterfacePointerType();
+        if (!OPT || OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()) {
+          CanBeInstanceMethod = CanBeClassMethod = true;
+          break;
+        }
+
+        if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType()) {
+          CanBeClassMethod = true;
+          break;
+        }
 
-      if (!OPT || OPT->isObjCIdType() || OPT->isObjCQualifiedIdType()) {
-        CanBeInstanceMethod = CanBeClassMethod = true;
+        MsgD = OPT->getInterfaceDecl();
+        assert(MsgD);
+        CanBeInstanceMethod = true;
         break;
       }
+        
+      case ObjCMessageExpr::Class:
+        CanBeClassMethod = true;
+        MsgD = Msg->getClassReceiver()->getAs<ObjCInterfaceType>()->getDecl();
+        break;
 
-      if (OPT->isObjCClassType() || OPT->isObjCQualifiedClassType()) {
+      case ObjCMessageExpr::SuperClass:
         CanBeClassMethod = true;
+        MsgD = Msg->getSuperType()->getAs<ObjCInterfaceType>()->getDecl();
         break;
-      }
 
-      MsgD = OPT->getInterfaceDecl();
-      assert(MsgD);
-      CanBeInstanceMethod = true;
-      break;
+      case ObjCMessageExpr::SuperInstance:
+        CanBeInstanceMethod = true;
+        MsgD = Msg->getSuperType()->getAs<ObjCObjectPointerType>()
+                                                           ->getInterfaceDecl();
+        break;
+      }
     }
 
     assert(CanBeInstanceMethod || CanBeClassMethod);

Modified: cfe/trunk/lib/Sema/SemaCodeComplete.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaCodeComplete.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaCodeComplete.cpp (original)
+++ cfe/trunk/lib/Sema/SemaCodeComplete.cpp Tue Apr 20 19:45:42 2010
@@ -2899,13 +2899,24 @@
     return 0;
 
   // Determine the class that we're sending the message to.
-  ObjCInterfaceDecl *IFace = Msg->getClassInfo().Decl;
-  if (!IFace) {
-    if (Expr *Receiver = Msg->getReceiver()) {
-      QualType T = Receiver->getType();
-      if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
-        IFace = Ptr->getInterfaceDecl();
-    }
+  ObjCInterfaceDecl *IFace = 0;
+  switch (Msg->getReceiverKind()) {
+  case ObjCMessageExpr::Class:
+    if (const ObjCInterfaceType *IFaceType
+                           = Msg->getClassReceiver()->getAs<ObjCInterfaceType>())
+      IFace = IFaceType->getDecl();
+    break;
+
+  case ObjCMessageExpr::Instance: {
+    QualType T = Msg->getInstanceReceiver()->getType();
+    if (const ObjCObjectPointerType *Ptr = T->getAs<ObjCObjectPointerType>())
+      IFace = Ptr->getInterfaceDecl();
+    break;
+  }
+
+  case ObjCMessageExpr::SuperInstance:
+  case ObjCMessageExpr::SuperClass:
+    break;
   }
 
   if (!IFace)

Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Tue Apr 20 19:45:42 2010
@@ -3130,10 +3130,10 @@
         if (DiagnoseUseOfDecl(OMD, MemberLoc))
           return ExprError();
 
-        return Owned(new (Context) ObjCMessageExpr(Context, BaseExpr, Sel,
-                                                   OMD->getResultType(),
-                                                   OMD, OpLoc, MemberLoc,
-                                                   NULL, 0));
+        return Owned(ObjCMessageExpr::Create(Context, 
+                                     OMD->getResultType().getNonReferenceType(),
+                                             OpLoc, BaseExpr, Sel,
+                                             OMD, NULL, 0, MemberLoc));
       }
     }
 

Modified: cfe/trunk/lib/Sema/SemaExprObjC.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExprObjC.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExprObjC.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExprObjC.cpp Tue Apr 20 19:45:42 2010
@@ -684,20 +684,19 @@
 
   returnType = returnType.getNonReferenceType();
 
-  // FIXME: need to do a better job handling 'super' usage within a class.  For
-  // now, we simply pass the "super" identifier through (which isn't consistent
-  // with instance methods.
+  QualType ReceiverType = Context.getObjCInterfaceType(ClassDecl);
   if (isSuper)
-    return new (Context) ObjCMessageExpr(Context, receiverName, receiverLoc,
-                                         Sel, returnType, Method, lbrac, rbrac,
-                                         ArgExprs, NumArgs);
+    return ObjCMessageExpr::Create(Context, returnType, lbrac, receiverLoc,
+                                   /*IsInstanceSuper=*/false,ReceiverType, 
+                                   Sel, Method, ArgExprs, NumArgs, rbrac);
   
   // If we have the ObjCInterfaceDecl* for the class that is receiving the
   // message, use that to construct the ObjCMessageExpr.  Otherwise pass on the
   // IdentifierInfo* for the class.
-  return new (Context) ObjCMessageExpr(Context, ClassDecl, receiverLoc,
-                                       Sel, returnType, Method, lbrac, rbrac, 
-                                       ArgExprs, NumArgs);
+  TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(ReceiverType,
+                                                            receiverLoc);
+  return ObjCMessageExpr::Create(Context, returnType, lbrac, TSInfo, Sel, 
+                                 Method, ArgExprs, NumArgs, rbrac);
 }
 
 // ActOnInstanceMessage - used for both unary and keyword messages.
@@ -717,6 +716,7 @@
   // C99 6.7.5.3p[7,8].
   DefaultFunctionArrayLvalueConversion(RExpr);
 
+  ObjCMethodDecl *Method = 0;
   QualType returnType;
   QualType ReceiverCType =
     Context.getCanonicalType(RExpr->getType()).getUnqualifiedType();
@@ -724,24 +724,15 @@
   // Handle messages to id.
   if (ReceiverCType->isObjCIdType() || ReceiverCType->isBlockPointerType() ||
       Context.isObjCNSObjectType(RExpr->getType())) {
-    ObjCMethodDecl *Method = LookupInstanceMethodInGlobalPool(
-                               Sel, SourceRange(lbrac,rbrac));
+    // FIXME: If our superclass is NSObject and we message 'super',
+    // we'll end up looking in the global method pool??
+
+    Method = LookupInstanceMethodInGlobalPool(Sel, SourceRange(lbrac,rbrac));
     if (!Method)
       Method = LookupFactoryMethodInGlobalPool(Sel, SourceRange(lbrac, rbrac));
-    if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
-                                  lbrac, rbrac, returnType))
-      return true;
-    returnType = returnType.getNonReferenceType();
-    return new (Context) ObjCMessageExpr(Context, RExpr, Sel, returnType,
-                                         Method, lbrac, rbrac,
-                                         ArgExprs, NumArgs);
-  }
-
-  // Handle messages to Class.
-  if (ReceiverCType->isObjCClassType() ||
-      ReceiverCType->isObjCQualifiedClassType()) {
-    ObjCMethodDecl *Method = 0;
-
+  } else if (ReceiverCType->isObjCClassType() ||
+             ReceiverCType->isObjCQualifiedClassType()) {
+    // Handle messages to Class.
     if (ObjCMethodDecl *CurMeth = getCurMethodDecl()) {
       if (ObjCInterfaceDecl *ClassDecl = CurMeth->getClassInterface()) {
         // First check the public methods in the class interface.
@@ -775,86 +766,78 @@
         }
       }
     }
-    if (CheckMessageArgumentTypes(ArgExprs, NumArgs, Sel, Method, false,
-                                  lbrac, rbrac, returnType))
-      return true;
-    returnType = returnType.getNonReferenceType();
-    return new (Context) ObjCMessageExpr(Context, RExpr, Sel, returnType,
-                                         Method, lbrac, rbrac,
-                                         ArgExprs, NumArgs);
-  }
-
-  ObjCMethodDecl *Method = 0;
-  ObjCInterfaceDecl* ClassDecl = 0;
+  } else {
+    ObjCInterfaceDecl* ClassDecl = 0;
 
-  // We allow sending a message to a qualified ID ("id<foo>"), which is ok as
-  // long as one of the protocols implements the selector (if not, warn).
-  if (const ObjCObjectPointerType *QIdTy =
+    // We allow sending a message to a qualified ID ("id<foo>"), which is ok as
+    // long as one of the protocols implements the selector (if not, warn).
+    if (const ObjCObjectPointerType *QIdTy =
         ReceiverCType->getAsObjCQualifiedIdType()) {
-    // Search protocols for instance methods.
-    for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(),
-         E = QIdTy->qual_end(); I != E; ++I) {
-      ObjCProtocolDecl *PDecl = *I;
-      if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
-        break;
-      // Since we aren't supporting "Class<foo>", look for a class method.
-      if (PDecl && (Method = PDecl->lookupClassMethod(Sel)))
-        break;
-    }
-  } else if (const ObjCObjectPointerType *OCIType =
-                ReceiverCType->getAsObjCInterfacePointerType()) {
-    // We allow sending a message to a pointer to an interface (an object).
-
-    ClassDecl = OCIType->getInterfaceDecl();
-    // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
-    // faster than the following method (which can do *many* linear searches).
-    // The idea is to add class info to InstanceMethodPool.
-    Method = ClassDecl->lookupInstanceMethod(Sel);
-
-    if (!Method) {
-      // Search protocol qualifiers.
-      for (ObjCObjectPointerType::qual_iterator QI = OCIType->qual_begin(),
-           E = OCIType->qual_end(); QI != E; ++QI) {
-        if ((Method = (*QI)->lookupInstanceMethod(Sel)))
+      // Search protocols for instance methods.
+      for (ObjCObjectPointerType::qual_iterator I = QIdTy->qual_begin(),
+             E = QIdTy->qual_end(); I != E; ++I) {
+        ObjCProtocolDecl *PDecl = *I;
+        if (PDecl && (Method = PDecl->lookupInstanceMethod(Sel)))
+          break;
+        // Since we aren't supporting "Class<foo>", look for a class method.
+        if (PDecl && (Method = PDecl->lookupClassMethod(Sel)))
           break;
       }
-    }
-    if (!Method) {
-      // If we have implementations in scope, check "private" methods.
-      Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
-
-      if (!Method && !isSelfExpr(RExpr)) {
-        // If we still haven't found a method, look in the global pool. This
-        // behavior isn't very desirable, however we need it for GCC
-        // compatibility. FIXME: should we deviate??
-        if (OCIType->qual_empty()) {
-          Method = LookupInstanceMethodInGlobalPool(
-                               Sel, SourceRange(lbrac,rbrac));
-          if (Method && !OCIType->getInterfaceDecl()->isForwardDecl())
-            Diag(lbrac, diag::warn_maynot_respond)
-              << OCIType->getInterfaceDecl()->getIdentifier() << Sel;
+    } else if (const ObjCObjectPointerType *OCIType =
+               ReceiverCType->getAsObjCInterfacePointerType()) {
+      // We allow sending a message to a pointer to an interface (an object).
+
+      ClassDecl = OCIType->getInterfaceDecl();
+      // FIXME: consider using LookupInstanceMethodInGlobalPool, since it will be
+      // faster than the following method (which can do *many* linear searches).
+      // The idea is to add class info to InstanceMethodPool.
+      Method = ClassDecl->lookupInstanceMethod(Sel);
+
+      if (!Method) {
+        // Search protocol qualifiers.
+        for (ObjCObjectPointerType::qual_iterator QI = OCIType->qual_begin(),
+               E = OCIType->qual_end(); QI != E; ++QI) {
+          if ((Method = (*QI)->lookupInstanceMethod(Sel)))
+            break;
         }
       }
-    }
-    if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
+      if (!Method) {
+        // If we have implementations in scope, check "private" methods.
+        Method = LookupPrivateInstanceMethod(Sel, ClassDecl);
+
+        if (!Method && !isSelfExpr(RExpr)) {
+          // If we still haven't found a method, look in the global pool. This
+          // behavior isn't very desirable, however we need it for GCC
+          // compatibility. FIXME: should we deviate??
+          if (OCIType->qual_empty()) {
+            Method = LookupInstanceMethodInGlobalPool(
+                                                Sel, SourceRange(lbrac,rbrac));
+            if (Method && !OCIType->getInterfaceDecl()->isForwardDecl())
+              Diag(lbrac, diag::warn_maynot_respond)
+                << OCIType->getInterfaceDecl()->getIdentifier() << Sel;
+          }
+        }
+      }
+      if (Method && DiagnoseUseOfDecl(Method, receiverLoc))
+        return true;
+    } else if (!Context.getObjCIdType().isNull() &&
+               (ReceiverCType->isPointerType() ||
+                (ReceiverCType->isIntegerType() &&
+                 ReceiverCType->isScalarType()))) {
+      // Implicitly convert integers and pointers to 'id' but emit a warning.
+      Diag(lbrac, diag::warn_bad_receiver_type)
+        << RExpr->getType() << RExpr->getSourceRange();
+      if (ReceiverCType->isPointerType())
+        ImpCastExprToType(RExpr, Context.getObjCIdType(), CastExpr::CK_BitCast);
+      else
+        ImpCastExprToType(RExpr, Context.getObjCIdType(),
+                          CastExpr::CK_IntegralToPointer);
+    } else {
+      // Reject other random receiver types (e.g. structs).
+      Diag(lbrac, diag::err_bad_receiver_type)
+        << RExpr->getType() << RExpr->getSourceRange();
       return true;
-  } else if (!Context.getObjCIdType().isNull() &&
-             (ReceiverCType->isPointerType() ||
-              (ReceiverCType->isIntegerType() &&
-               ReceiverCType->isScalarType()))) {
-    // Implicitly convert integers and pointers to 'id' but emit a warning.
-    Diag(lbrac, diag::warn_bad_receiver_type)
-      << RExpr->getType() << RExpr->getSourceRange();
-    if (ReceiverCType->isPointerType())
-      ImpCastExprToType(RExpr, Context.getObjCIdType(), CastExpr::CK_BitCast);
-    else
-      ImpCastExprToType(RExpr, Context.getObjCIdType(),
-                        CastExpr::CK_IntegralToPointer);
-  } else {
-    // Reject other random receiver types (e.g. structs).
-    Diag(lbrac, diag::err_bad_receiver_type)
-      << RExpr->getType() << RExpr->getSourceRange();
-    return true;
+    }
   }
 
   if (Method)
@@ -863,7 +846,15 @@
                                 lbrac, rbrac, returnType))
     return true;
   returnType = returnType.getNonReferenceType();
-  return new (Context) ObjCMessageExpr(Context, RExpr, Sel, returnType, Method,
-                                       lbrac, rbrac, ArgExprs, NumArgs);
+
+  if (isa<ObjCSuperExpr>(RExpr))
+    return ObjCMessageExpr::Create(Context, returnType, lbrac,
+                                   RExpr->getLocStart(), 
+                                   /*IsInstanceSuper=*/true,
+                                   RExpr->getType(),
+                                   Sel, Method, ArgExprs, NumArgs, rbrac);
+
+  return ObjCMessageExpr::Create(Context, returnType, lbrac, RExpr, Sel,
+                                 Method, ArgExprs, NumArgs, rbrac);
 }
 

Modified: cfe/trunk/tools/CIndex/CIndex.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/tools/CIndex/CIndex.cpp?rev=101972&r1=101971&r2=101972&view=diff
==============================================================================
--- cfe/trunk/tools/CIndex/CIndex.cpp (original)
+++ cfe/trunk/tools/CIndex/CIndex.cpp Tue Apr 20 19:45:42 2010
@@ -971,9 +971,9 @@
 }
 
 bool CursorVisitor::VisitObjCMessageExpr(ObjCMessageExpr *E) {
-  ObjCMessageExpr::ClassInfo CI = E->getClassInfo();
-  if (CI.Decl && Visit(MakeCursorObjCClassRef(CI.Decl, CI.Loc, TU)))
-    return true;
+  if (TypeSourceInfo *TSInfo = E->getClassReceiverTypeInfo())
+    if (Visit(TSInfo->getTypeLoc()))
+      return true;
 
   return VisitExpr(E);
 }





More information about the cfe-commits mailing list