diff options
| author | Douglas Gregor <dgregor@apple.com> | 2010-04-21 00:45:42 +0000 | 
|---|---|---|
| committer | Douglas Gregor <dgregor@apple.com> | 2010-04-21 00:45:42 +0000 | 
| commit | 9a1291942127751d4621f930d048fe22496e9681 (patch) | |
| tree | 8144f1d1e9757feb6a4993ba298ac25b1d2fec86 /clang/lib/Frontend/PCHWriterStmt.cpp | |
| parent | 2034d9f2da93cd830f4f1ed568f71c1a232e3ed7 (diff) | |
| download | bcm5719-llvm-9a1291942127751d4621f930d048fe22496e9681.tar.gz bcm5719-llvm-9a1291942127751d4621f930d048fe22496e9681.zip | |
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.
llvm-svn: 101972
Diffstat (limited to 'clang/lib/Frontend/PCHWriterStmt.cpp')
| -rw-r--r-- | clang/lib/Frontend/PCHWriterStmt.cpp | 35 | 
1 files changed, 25 insertions, 10 deletions
| diff --git a/clang/lib/Frontend/PCHWriterStmt.cpp b/clang/lib/Frontend/PCHWriterStmt.cpp index 9c9f8911157..9a9539bb547 100644 --- a/clang/lib/Frontend/PCHWriterStmt.cpp +++ b/clang/lib/Frontend/PCHWriterStmt.cpp @@ -712,18 +712,33 @@ void PCHStmtWriter::VisitObjCImplicitSetterGetterRefExpr(  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) | 

